linux/samples/timers/hpet_example.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <stdio.h>
   3#include <stdlib.h>
   4#include <unistd.h>
   5#include <fcntl.h>
   6#include <string.h>
   7#include <memory.h>
   8#include <malloc.h>
   9#include <time.h>
  10#include <ctype.h>
  11#include <sys/types.h>
  12#include <sys/wait.h>
  13#include <signal.h>
  14#include <errno.h>
  15#include <sys/time.h>
  16#include <linux/hpet.h>
  17
  18
  19extern void hpet_open_close(int, const char **);
  20extern void hpet_info(int, const char **);
  21extern void hpet_poll(int, const char **);
  22extern void hpet_fasync(int, const char **);
  23extern void hpet_read(int, const char **);
  24
  25#include <sys/poll.h>
  26#include <sys/ioctl.h>
  27
  28struct hpet_command {
  29        char            *command;
  30        void            (*func)(int argc, const char ** argv);
  31} hpet_command[] = {
  32        {
  33                "open-close",
  34                hpet_open_close
  35        },
  36        {
  37                "info",
  38                hpet_info
  39        },
  40        {
  41                "poll",
  42                hpet_poll
  43        },
  44        {
  45                "fasync",
  46                hpet_fasync
  47        },
  48};
  49
  50int
  51main(int argc, const char ** argv)
  52{
  53        unsigned int    i;
  54
  55        argc--;
  56        argv++;
  57
  58        if (!argc) {
  59                fprintf(stderr, "-hpet: requires command\n");
  60                return -1;
  61        }
  62
  63
  64        for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
  65                if (!strcmp(argv[0], hpet_command[i].command)) {
  66                        argc--;
  67                        argv++;
  68                        fprintf(stderr, "-hpet: executing %s\n",
  69                                hpet_command[i].command);
  70                        hpet_command[i].func(argc, argv);
  71                        return 0;
  72                }
  73
  74        fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
  75
  76        return -1;
  77}
  78
  79void
  80hpet_open_close(int argc, const char **argv)
  81{
  82        int     fd;
  83
  84        if (argc != 1) {
  85                fprintf(stderr, "hpet_open_close: device-name\n");
  86                return;
  87        }
  88
  89        fd = open(argv[0], O_RDONLY);
  90        if (fd < 0)
  91                fprintf(stderr, "hpet_open_close: open failed\n");
  92        else
  93                close(fd);
  94
  95        return;
  96}
  97
  98void
  99hpet_info(int argc, const char **argv)
 100{
 101        struct hpet_info        info;
 102        int                     fd;
 103
 104        if (argc != 1) {
 105                fprintf(stderr, "hpet_info: device-name\n");
 106                return;
 107        }
 108
 109        fd = open(argv[0], O_RDONLY);
 110        if (fd < 0) {
 111                fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
 112                return;
 113        }
 114
 115        if (ioctl(fd, HPET_INFO, &info) < 0) {
 116                fprintf(stderr, "hpet_info: failed to get info\n");
 117                goto out;
 118        }
 119
 120        fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
 121                info.hi_ireqfreq, info.hi_flags);
 122        fprintf(stderr, "hi_hpet %d hi_timer %d\n",
 123                info.hi_hpet, info.hi_timer);
 124
 125out:
 126        close(fd);
 127        return;
 128}
 129
 130void
 131hpet_poll(int argc, const char **argv)
 132{
 133        unsigned long           freq;
 134        int                     iterations, i, fd;
 135        struct pollfd           pfd;
 136        struct hpet_info        info;
 137        struct timeval          stv, etv;
 138        struct timezone         tz;
 139        long                    usec;
 140
 141        if (argc != 3) {
 142                fprintf(stderr, "hpet_poll: device-name freq iterations\n");
 143                return;
 144        }
 145
 146        freq = atoi(argv[1]);
 147        iterations = atoi(argv[2]);
 148
 149        fd = open(argv[0], O_RDONLY);
 150
 151        if (fd < 0) {
 152                fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
 153                return;
 154        }
 155
 156        if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
 157                fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
 158                goto out;
 159        }
 160
 161        if (ioctl(fd, HPET_INFO, &info) < 0) {
 162                fprintf(stderr, "hpet_poll: failed to get info\n");
 163                goto out;
 164        }
 165
 166        fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
 167
 168        if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
 169                fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
 170                goto out;
 171        }
 172
 173        if (ioctl(fd, HPET_IE_ON, 0) < 0) {
 174                fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
 175                goto out;
 176        }
 177
 178        pfd.fd = fd;
 179        pfd.events = POLLIN;
 180
 181        for (i = 0; i < iterations; i++) {
 182                pfd.revents = 0;
 183                gettimeofday(&stv, &tz);
 184                if (poll(&pfd, 1, -1) < 0)
 185                        fprintf(stderr, "hpet_poll: poll failed\n");
 186                else {
 187                        long    data;
 188
 189                        gettimeofday(&etv, &tz);
 190                        usec = stv.tv_sec * 1000000 + stv.tv_usec;
 191                        usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
 192
 193                        fprintf(stderr,
 194                                "hpet_poll: expired time = 0x%lx\n", usec);
 195
 196                        fprintf(stderr, "hpet_poll: revents = 0x%x\n",
 197                                pfd.revents);
 198
 199                        if (read(fd, &data, sizeof(data)) != sizeof(data)) {
 200                                fprintf(stderr, "hpet_poll: read failed\n");
 201                        }
 202                        else
 203                                fprintf(stderr, "hpet_poll: data 0x%lx\n",
 204                                        data);
 205                }
 206        }
 207
 208out:
 209        close(fd);
 210        return;
 211}
 212
 213static int hpet_sigio_count;
 214
 215static void
 216hpet_sigio(int val)
 217{
 218        fprintf(stderr, "hpet_sigio: called\n");
 219        hpet_sigio_count++;
 220}
 221
 222void
 223hpet_fasync(int argc, const char **argv)
 224{
 225        unsigned long           freq;
 226        int                     iterations, i, fd, value;
 227        sig_t                   oldsig;
 228        struct hpet_info        info;
 229
 230        hpet_sigio_count = 0;
 231        fd = -1;
 232
 233        if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
 234                fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
 235                return;
 236        }
 237
 238        if (argc != 3) {
 239                fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
 240                goto out;
 241        }
 242
 243        fd = open(argv[0], O_RDONLY);
 244
 245        if (fd < 0) {
 246                fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
 247                return;
 248        }
 249
 250
 251        if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
 252                ((value = fcntl(fd, F_GETFL)) == 1) ||
 253                (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
 254                fprintf(stderr, "hpet_fasync: fcntl failed\n");
 255                goto out;
 256        }
 257
 258        freq = atoi(argv[1]);
 259        iterations = atoi(argv[2]);
 260
 261        if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
 262                fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
 263                goto out;
 264        }
 265
 266        if (ioctl(fd, HPET_INFO, &info) < 0) {
 267                fprintf(stderr, "hpet_fasync: failed to get info\n");
 268                goto out;
 269        }
 270
 271        fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
 272
 273        if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
 274                fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
 275                goto out;
 276        }
 277
 278        if (ioctl(fd, HPET_IE_ON, 0) < 0) {
 279                fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
 280                goto out;
 281        }
 282
 283        for (i = 0; i < iterations; i++) {
 284                (void) pause();
 285                fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
 286        }
 287
 288out:
 289        signal(SIGIO, oldsig);
 290
 291        if (fd >= 0)
 292                close(fd);
 293
 294        return;
 295}
 296