aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pps
diff options
context:
space:
mode:
authorRodolfo Giometti <giometti@linux.it>2009-11-11 17:26:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-11-12 10:26:01 -0500
commit276b282e904f690dc930f9bc946110651f297669 (patch)
tree7e50db4cee555f6044bd389452269d3c0fe45ed6 /drivers/pps
parentcbf83cc5a29dba480cf1ba1c5e3417a0d4a31410 (diff)
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: Rodolfo Giometti <giometti@linux.it> Tested-by: William S. Brasher <billb958@door.net> Tested-by: Reg Clemens <clemens@dwf.com> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/pps')
-rw-r--r--drivers/pps/kapi.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index 35a0b192d768..2d414e23d390 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -271,6 +271,7 @@ void pps_event(int source, struct pps_ktime *ts, int event, void *data)
271{ 271{
272 struct pps_device *pps; 272 struct pps_device *pps;
273 unsigned long flags; 273 unsigned long flags;
274 int captured = 0;
274 275
275 if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0) { 276 if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0) {
276 printk(KERN_ERR "pps: unknown event (%x) for source %d\n", 277 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)
293 294
294 /* Check the event */ 295 /* Check the event */
295 pps->current_mode = pps->params.mode; 296 pps->current_mode = pps->params.mode;
296 if (event & PPS_CAPTUREASSERT) { 297 if ((event & PPS_CAPTUREASSERT) &
298 (pps->params.mode & PPS_CAPTUREASSERT)) {
297 /* We have to add an offset? */ 299 /* We have to add an offset? */
298 if (pps->params.mode & PPS_OFFSETASSERT) 300 if (pps->params.mode & PPS_OFFSETASSERT)
299 pps_add_offset(ts, &pps->params.assert_off_tu); 301 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)
303 pps->assert_sequence++; 305 pps->assert_sequence++;
304 pr_debug("capture assert seq #%u for source %d\n", 306 pr_debug("capture assert seq #%u for source %d\n",
305 pps->assert_sequence, source); 307 pps->assert_sequence, source);
308
309 captured = ~0;
306 } 310 }
307 if (event & PPS_CAPTURECLEAR) { 311 if ((event & PPS_CAPTURECLEAR) &
312 (pps->params.mode & PPS_CAPTURECLEAR)) {
308 /* We have to add an offset? */ 313 /* We have to add an offset? */
309 if (pps->params.mode & PPS_OFFSETCLEAR) 314 if (pps->params.mode & PPS_OFFSETCLEAR)
310 pps_add_offset(ts, &pps->params.clear_off_tu); 315 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)
314 pps->clear_sequence++; 319 pps->clear_sequence++;
315 pr_debug("capture clear seq #%u for source %d\n", 320 pr_debug("capture clear seq #%u for source %d\n",
316 pps->clear_sequence, source); 321 pps->clear_sequence, source);
322
323 captured = ~0;
317 } 324 }
318 325
319 pps->go = ~0; 326 /* Wake up iif captured somthing */
320 wake_up_interruptible(&pps->queue); 327 if (captured) {
328 pps->go = ~0;
329 wake_up_interruptible(&pps->queue);
321 330
322 kill_fasync(&pps->async_queue, SIGIO, POLL_IN); 331 kill_fasync(&pps->async_queue, SIGIO, POLL_IN);
332 }
323 333
324 spin_unlock_irqrestore(&pps->lock, flags); 334 spin_unlock_irqrestore(&pps->lock, flags);
325 335