#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <linux/hpet.h>


extern void hpet_open_close(int, const char **);
extern void hpet_info(int, const char **);
extern void hpet_poll(int, const char **);
extern void hpet_fasync(int, const char **);
extern void hpet_read(int, const char **);

#include <sys/poll.h>
#include <sys/ioctl.h>

struct hpet_command {
	char		*command;
	void		(*func)(int argc, const char ** argv);
} hpet_command[] = {
	{
		"open-close",
		hpet_open_close
	},
	{
		"info",
		hpet_info
	},
	{
		"poll",
		hpet_poll
	},
	{
		"fasync",
		hpet_fasync
	},
};

int
main(int argc, const char ** argv)
{
	unsigned int	i;

	argc--;
	argv++;

	if (!argc) {
		fprintf(stderr, "-hpet: requires command\n");
		return -1;
	}


	for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
		if (!strcmp(argv[0], hpet_command[i].command)) {
			argc--;
			argv++;
			fprintf(stderr, "-hpet: executing %s\n",
				hpet_command[i].command);
			hpet_command[i].func(argc, argv);
			return 0;
		}

	fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);

	return -1;
}

void
hpet_open_close(int argc, const char **argv)
{
	int	fd;

	if (argc != 1) {
		fprintf(stderr, "hpet_open_close: device-name\n");
		return;
	}

	fd = open(argv[0], O_RDONLY);
	if (fd < 0)
		fprintf(stderr, "hpet_open_close: open failed\n");
	else
		close(fd);

	return;
}

void
hpet_info(int argc, const char **argv)
{
	struct hpet_info	info;
	int			fd;

	if (argc != 1) {
		fprintf(stderr, "hpet_info: device-name\n");
		return;
	}

	fd = open(argv[0], O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
		return;
	}

	if (ioctl(fd, HPET_INFO, &info) < 0) {
		fprintf(stderr, "hpet_info: failed to get info\n");
		goto out;
	}

	fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
		info.hi_ireqfreq, info.hi_flags);
	fprintf(stderr, "hi_hpet %d hi_timer %d\n",
		info.hi_hpet, info.hi_timer);

out:
	close(fd);
	return;
}

void
hpet_poll(int argc, const char **argv)
{
	unsigned long		freq;
	int			iterations, i, fd;
	struct pollfd		pfd;
	struct hpet_info	info;
	struct timeval		stv, etv;
	struct timezone		tz;
	long			usec;

	if (argc != 3) {
		fprintf(stderr, "hpet_poll: device-name freq iterations\n");
		return;
	}

	freq = atoi(argv[1]);
	iterations = atoi(argv[2]);

	fd = open(argv[0], O_RDONLY);

	if (fd < 0) {
		fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
		return;
	}

	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
		fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
		goto out;
	}

	if (ioctl(fd, HPET_INFO, &info) < 0) {
		fprintf(stderr, "hpet_poll: failed to get info\n");
		goto out;
	}

	fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);

	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
		fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
		goto out;
	}

	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
		fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
		goto out;
	}

	pfd.fd = fd;
	pfd.events = POLLIN;

	for (i = 0; i < iterations; i++) {
		pfd.revents = 0;
		gettimeofday(&stv, &tz);
		if (poll(&pfd, 1, -1) < 0)
			fprintf(stderr, "hpet_poll: poll failed\n");
		else {
			long 	data;

			gettimeofday(&etv, &tz);
			usec = stv.tv_sec * 1000000 + stv.tv_usec;
			usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;

			fprintf(stderr,
				"hpet_poll: expired time = 0x%lx\n", usec);

			fprintf(stderr, "hpet_poll: revents = 0x%x\n",
				pfd.revents);

			if (read(fd, &data, sizeof(data)) != sizeof(data)) {
				fprintf(stderr, "hpet_poll: read failed\n");
			}
			else
				fprintf(stderr, "hpet_poll: data 0x%lx\n",
					data);
		}
	}

out:
	close(fd);
	return;
}

static int hpet_sigio_count;

static void
hpet_sigio(int val)
{
	fprintf(stderr, "hpet_sigio: called\n");
	hpet_sigio_count++;
}

void
hpet_fasync(int argc, const char **argv)
{
	unsigned long		freq;
	int			iterations, i, fd, value;
	sig_t			oldsig;
	struct hpet_info	info;

	hpet_sigio_count = 0;
	fd = -1;

	if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
		fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
		return;
	}

	if (argc != 3) {
		fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
		goto out;
	}

	fd = open(argv[0], O_RDONLY);

	if (fd < 0) {
		fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
		return;
	}


	if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
		((value = fcntl(fd, F_GETFL)) == 1) ||
		(fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
		fprintf(stderr, "hpet_fasync: fcntl failed\n");
		goto out;
	}

	freq = atoi(argv[1]);
	iterations = atoi(argv[2]);

	if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
		fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
		goto out;
	}

	if (ioctl(fd, HPET_INFO, &info) < 0) {
		fprintf(stderr, "hpet_fasync: failed to get info\n");
		goto out;
	}

	fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);

	if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
		fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
		goto out;
	}

	if (ioctl(fd, HPET_IE_ON, 0) < 0) {
		fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
		goto out;
	}

	for (i = 0; i < iterations; i++) {
		(void) pause();
		fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
	}

out:
	signal(SIGIO, oldsig);

	if (fd >= 0)
		close(fd);

	return;
}
05cf6823087f9696db8c0c8f144b02</a> /<a href='/cgit.cgi/linux/net-next.git/tree/kernel/kmod.c?h=nds-private-remove&amp;id=3ddc76dfc786cc6f87852693227fb0b1f124f807'>kernel/kmod.c</a></td></tr>
<tr><th>parent</th><td colspan='2' class='oid'><a href='/cgit.cgi/linux/net-next.git/commit/kernel/kmod.c?h=nds-private-remove&amp;id=b272f732f888d4cf43c943a40c9aaa836f9b7431'>b272f732f888d4cf43c943a40c9aaa836f9b7431</a> (<a href='/cgit.cgi/linux/net-next.git/diff/kernel/kmod.c?h=nds-private-remove&amp;id=3ddc76dfc786cc6f87852693227fb0b1f124f807&amp;id2=b272f732f888d4cf43c943a40c9aaa836f9b7431'>diff</a>)</td></tr><tr><th>parent</th><td colspan='2' class='oid'><a href='/cgit.cgi/linux/net-next.git/commit/kernel/kmod.c?h=nds-private-remove&amp;id=1f3a8e49d8f28f498b8694464623ac20aebfe62a'>1f3a8e49d8f28f498b8694464623ac20aebfe62a</a> (<a href='/cgit.cgi/linux/net-next.git/diff/kernel/kmod.c?h=nds-private-remove&amp;id=3ddc76dfc786cc6f87852693227fb0b1f124f807&amp;id2=1f3a8e49d8f28f498b8694464623ac20aebfe62a'>diff</a>)</td></tr></table>
<div class='commit-subject'>Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip</div><div class='commit-msg'>Pull timer type cleanups from Thomas Gleixner:
 "This series does a tree wide cleanup of types related to
  timers/timekeeping.

   - Get rid of cycles_t and use a plain u64. The type is not really
     helpful and caused more confusion than clarity

   - Get rid of the ktime union. The union has become useless as we use
     the scalar nanoseconds storage unconditionally now. The 32bit
     timespec alike storage got removed due to the Y2038 limitations
     some time ago.

     That leaves the odd union access around for no reason. Clean it up.

  Both changes have been done with coccinelle and a small amount of
  manual mopping up"

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  ktime: Get rid of ktime_equal()
  ktime: Cleanup ktime_set() usage
  ktime: Get rid of the union
  clocksource: Use a plain u64 instead of cycle_t
</div><div class='diffstat-header'><a href='/cgit.cgi/linux/net-next.git/diff/?h=nds-private-remove&amp;id=3ddc76dfc786cc6f87852693227fb0b1f124f807'>Diffstat</a> (limited to 'kernel/kmod.c')</div><table summary='diffstat' class='diffstat'>