#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <sys/inotify.h>
+#include <stdint.h>
+#include <poll.h>
 #include <sys/types.h>
 #include <time.h>
 #include <unistd.h>
 #define CSV_MAX_LINE   0x1000
 #define SYSFS_MAX_INT  0x20
 #define MAX_STR_LEN    255
-#define MAX_TIMEOUT_COUNT 5
-#define TIMEOUT_SEC 1
+#define DEFAULT_POLL_TIMEOUT_SEC 30
 #define DEFAULT_ASYNC_TIMEOUT 200000
 
 struct dict {
        char name[MAX_SYSFS_PATH];
        char sysfs_entry[MAX_SYSFS_PATH];
        char debugfs_entry[MAX_SYSFS_PATH];
-       int inotify_wd;
        struct loopback_results results;
 };
 
        int aggregate_output;
        int test_id;
        int device_count;
-       int inotify_fd;
        int list_devices;
        int use_async;
        int async_timeout;
+       int poll_timeout;
        int async_outstanding_operations;
        int us_wait;
        int file_output;
+       int poll_count;
        char test_name[MAX_STR_LEN];
        char sysfs_prefix[MAX_SYSFS_PATH];
        char debugfs_prefix[MAX_SYSFS_PATH];
        struct loopback_device devices[MAX_NUM_DEVICES];
        struct loopback_results aggregate_results;
+       struct pollfd fds[MAX_NUM_DEVICES];
 };
+
 struct loopback_test t;
 
 /* Helper macros to calculate the aggregate results for all devices */
        "   -l     list found loopback devices and exit\n"
        "   -x     Async - Enable async transfers\n"
        "   -o     Async Timeout - Timeout in uSec for async operations\n"
+       "   -O     Poll loop time out in seconds(max time a test is expected to last, default: 30sec)\n"
        "   -c     Max number of outstanding operations for async operations\n"
        "   -w     Wait in uSec between operations\n"
        "   -z     Enable output to a CSV file (incompatible with -p)\n"
        return ret;
 }
 
-
-static int register_for_notification(struct loopback_test *t)
+static int open_poll_files(struct loopback_test *t)
 {
-       char buf[MAX_SYSFS_PATH];
+       struct loopback_device *dev;
+       char buf[MAX_STR_LEN];
+       char dummy;
+       int fds_idx = 0;
        int i;
 
-       t->inotify_fd = inotify_init();
-       if (t->inotify_fd < 0) {
-               fprintf(stderr, "inotify_init fail %s\n", strerror(errno));
-               abort();
-       }
-
        for (i = 0; i < t->device_count; i++) {
+               dev = &t->devices[i];
+
                if (!device_enabled(t, i))
                        continue;
 
-               snprintf(buf, sizeof(buf), "%s%s", t->devices[i].sysfs_entry,
-                       "iteration_count");
-
-               t->devices[i].inotify_wd = inotify_add_watch(t->inotify_fd,
-                                                       buf, IN_MODIFY);
-               if (t->devices[i].inotify_wd < 0) {
-                       fprintf(stderr, "inotify_add_watch %s fail %s\n",
-                               buf, strerror(errno));
-                       close(t->inotify_fd);
-                       abort();
+               snprintf(buf, sizeof(buf), "%s%s", dev->sysfs_entry, "iteration_count");
+               t->fds[fds_idx].fd = open(buf, O_RDONLY);
+               if (t->fds[fds_idx].fd < 0) {
+                       fprintf(stderr, "Error opening poll file!\n");
+                       goto err;
                }
+               read(t->fds[fds_idx].fd, &dummy, 1);
+               t->fds[fds_idx].events = POLLERR|POLLPRI;
+               t->fds[fds_idx].revents = 0;
+               fds_idx++;
        }
 
+       t->poll_count = fds_idx;
+
        return 0;
+
+err:
+       for (i = 0; i < fds_idx; i++)
+               close(t->fds[fds_idx].fd);
+
+       return -1;
 }
 
-static int unregister_for_notification(struct loopback_test *t)
+static int close_poll_files(struct loopback_test *t)
 {
        int i;
-       int ret = 0;
-
-       for (i = 0; i < t->device_count; i++) {
-               if (!device_enabled(t, i))
-                       continue;
-
-               ret = inotify_rm_watch(t->inotify_fd, t->devices[i].inotify_wd);
-               if (ret) {
-                       fprintf(stderr, "inotify_rm_watch error.\n");
-                       return ret;
-               }
-       }
+       for (i = 0; i < t->poll_count; i++)
+               close(t->fds[i].fd);
 
-       close(t->inotify_fd);
        return 0;
 }
-
 static int is_complete(struct loopback_test *t)
 {
        int iteration_count;
 
 static int wait_for_complete(struct loopback_test *t)
 {
-       int remaining_timeouts = MAX_TIMEOUT_COUNT;
-       char buf[MAX_SYSFS_PATH];
-       struct timeval timeout;
-       fd_set read_fds;
+       int number_of_events = 0;
+       char dummy;
        int ret;
+       int i;
 
        while (1) {
-               /* Wait for change */
-               timeout.tv_sec = TIMEOUT_SEC;
-               timeout.tv_usec = 0;
-               FD_ZERO(&read_fds);
-               FD_SET(t->inotify_fd, &read_fds);
-               ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
-               if (ret < 0) {
-                       fprintf(stderr, "Select error.\n");
+               ret = poll(t->fds, t->poll_count, DEFAULT_POLL_TIMEOUT_SEC * 1000);
+               if (ret == 0) {
+                       fprintf(stderr, "Poll timmed out!\n");
                        return -1;
                }
 
-               /* timeout - test may be finished.*/
-               if (!FD_ISSET(t->inotify_fd, &read_fds)) {
-                       remaining_timeouts--;
-
-                       if (is_complete(t))
-                               return 0;
+               if (ret < 0) {
+                       fprintf(stderr, "Poll Error!\n");
+                       return -1;
+               }
 
-                       if (!remaining_timeouts) {
-                               fprintf(stderr, "Too many timeouts\n");
-                               return -1;
+               for (i = 0; i < t->poll_count; i++) {
+                       if (t->fds[i].revents & POLLPRI) {
+                               /* Dummy read to clear the event */
+                               read(t->fds[i].fd, &dummy, 1);
+                               number_of_events++;
                        }
-               } else {
-                       /* read to clear the event */
-                       ret = read(t->inotify_fd, buf, sizeof(buf));
                }
+
+               if (number_of_events == t->poll_count)
+                       break;
+       }
+
+       if (!is_complete(t)) {
+               fprintf(stderr, "Iteration count did not finish!\n");
+               return -1;
        }
 
        return 0;
 
        prepare_devices(t);
 
-       ret = register_for_notification(t);
+       ret = open_poll_files(t);
        if (ret)
                goto err;
 
        start(t);
 
-       sleep(1);
-
-       wait_for_complete(t);
+       ret = wait_for_complete(t);
+       close_poll_files(t);
+       if (ret)
+               goto err;
 
-       unregister_for_notification(t);
 
        get_results(t);
 
        memset(&t, 0, sizeof(t));
 
        while ((o = getopt(argc, argv,
-                          "t:s:i:S:D:m:v::d::r::p::a::l::x::o:c:w:")) != -1) {
+                          "t:s:i:S:D:m:v::d::r::p::a::l::x::o:c:w:O:")) != -1) {
                switch (o) {
                case 't':
                        snprintf(t.test_name, MAX_STR_LEN, "%s", optarg);
                case 'o':
                        t.async_timeout = atoi(optarg);
                        break;
+               case 'O':
+                       t.poll_timeout = atoi(optarg);
+                       break;
                case 'c':
                        t.async_outstanding_operations = atoi(optarg);
                        break;
        if (t.async_timeout == 0)
                t.async_timeout = DEFAULT_ASYNC_TIMEOUT;
 
+       if (t.poll_timeout == 0)
+               t.poll_timeout = DEFAULT_POLL_TIMEOUT_SEC;
+
        loopback_run(&t);
 
        return 0;