39
39
#include <nuttx/fs/fs.h>
40
40
#include <nuttx/mutex.h>
41
41
#include <nuttx/timers/timer.h>
42
+ #include <sys/poll.h>
42
43
43
44
#ifdef CONFIG_TIMER
44
45
@@ -53,6 +54,7 @@ struct timer_upperhalf_s
53
54
mutex_t lock ; /* Supports mutual exclusion */
54
55
uint8_t crefs ; /* The number of times the device has been opened */
55
56
FAR char * path ; /* Registration path */
57
+ FAR struct pollfd * fds ;
56
58
57
59
/* The contained signal info */
58
60
@@ -77,6 +79,8 @@ static ssize_t timer_write(FAR struct file *filep, FAR const char *buffer,
77
79
size_t buflen );
78
80
static int timer_ioctl (FAR struct file * filep , int cmd ,
79
81
unsigned long arg );
82
+ static int timer_poll (FAR struct file * filep ,
83
+ FAR struct pollfd * fds , bool setup );
80
84
81
85
/****************************************************************************
82
86
* Private Data
@@ -90,6 +94,9 @@ static const struct file_operations g_timerops =
90
94
timer_write , /* write */
91
95
NULL , /* seek */
92
96
timer_ioctl , /* ioctl */
97
+ NULL , /* mmap */
98
+ NULL , /* truncate */
99
+ timer_poll , /* poll */
93
100
};
94
101
95
102
/****************************************************************************
@@ -115,6 +122,8 @@ static bool timer_notifier(FAR uint32_t *next_interval_us, FAR void *arg)
115
122
116
123
/* Signal the waiter.. if there is one */
117
124
125
+ poll_notify (& upper -> fds , 1 , POLLIN );
126
+
118
127
nxsig_notification (notify -> pid , & notify -> event , SI_QUEUE , & upper -> work );
119
128
120
129
return notify -> periodic ;
@@ -396,6 +405,46 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
396
405
return ret ;
397
406
}
398
407
408
+ /****************************************************************************
409
+ * Name: timer_poll
410
+ ****************************************************************************/
411
+
412
+ static int timer_poll (FAR struct file * filep ,
413
+ FAR struct pollfd * fds , bool setup )
414
+ {
415
+ FAR struct inode * inode = filep -> f_inode ;
416
+ FAR struct timer_upperhalf_s * upper = inode -> i_private ;
417
+ irqstate_t flags ;
418
+ int ret = OK ;
419
+
420
+ if (upper == NULL || fds == NULL )
421
+ {
422
+ return - EINVAL ;
423
+ }
424
+
425
+ flags = enter_critical_section ();
426
+
427
+ if (setup )
428
+ {
429
+ if (upper -> fds )
430
+ {
431
+ ret = - EBUSY ;
432
+ goto errout ;
433
+ }
434
+
435
+ upper -> fds = fds ;
436
+ }
437
+ else
438
+ {
439
+ upper -> fds = NULL ;
440
+ }
441
+
442
+ errout :
443
+ leave_critical_section (flags );
444
+
445
+ return ret ;
446
+ }
447
+
399
448
/****************************************************************************
400
449
* Public Functions
401
450
****************************************************************************/
@@ -560,7 +609,7 @@ int timer_setcallback(FAR void *handle, tccb_t callback, FAR void *arg)
560
609
561
610
/* Check if the lower half driver supports the setcallback method */
562
611
563
- if (lower -> ops -> setcallback != NULL ) /* Optional */
612
+ if (lower -> ops -> setcallback != NULL )
564
613
{
565
614
/* Yes.. Defer the handler attachment to the lower half driver */
566
615
0 commit comments