On Mon, 2010-05-17 at 15:25 +0800, Jason Wang wrote: > This new autotest module implements a simple test for the driver of realtime > clock. It do the testing of interrupt, date reading, alarm and > frequency. Ok, patchset applied, thank you! > Please refer the Documentation/rtc.txt for details. > > Signed-off-by: Jason Wang <jasowang@xxxxxxxxxx> > --- > client/tests/rtc/src/Makefile | 19 +++ > client/tests/rtc/src/rtctest.c | 261 ++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 280 insertions(+), 0 deletions(-) > create mode 100644 client/tests/rtc/src/Makefile > create mode 100644 client/tests/rtc/src/rtctest.c > > diff --git a/client/tests/rtc/control b/client/tests/rtc/control > new file mode 100644 > index 0000000..f0f64c9 > --- /dev/null > +++ b/client/tests/rtc/control > @@ -0,0 +1,15 @@ > +TIME="SHORT" > +AUTHOR = "Jason Wang <jasowag@xxxxxxxxxx>" > +DOC = """ > +rtc is a simple test of realtime clock driver which was grabbed from > +Documentation/rtc.txt. It does the functional test of interrupt, alarm and > +requeseted frequency. > + > +Please refer the kernel documentation for details. > +""" > +NAME = 'rtc' > +TEST_CLASS = 'kernel' > +TEST_CATEGORY = 'Functional' > +TEST_TYPE = 'client' > + > +job.run_test('rtc') > diff --git a/client/tests/rtc/rtc.py b/client/tests/rtc/rtc.py > new file mode 100644 > index 0000000..d4a1500 > --- /dev/null > +++ b/client/tests/rtc/rtc.py > @@ -0,0 +1,23 @@ > +import os > +from autotest_lib.client.bin import test, utils > +from autotest_lib.client.common_lib import error > + > +class rtc(test.test): > + version = 1 > + > + preserve_srcdir = True > + > + def setup(self): > + os.chdir(self.srcdir) > + utils.system('make') > + > + > + def initialize(self): > + self.job.require_gcc() > + > + > + def run_once(self, def_rtc="/dev/rtc0", maxfreq=64): > + if not os.path.exists(def_rtc): > + raise error.TestNAError("%s doest not existed." % def_rtc) > + result = utils.system(self.srcdir + '/rtctest %s %s' % (def_rtc, > + maxfreq)) > diff --git a/client/tests/rtc/src/Makefile b/client/tests/rtc/src/Makefile > new file mode 100644 > index 0000000..f99dc60 > --- /dev/null > +++ b/client/tests/rtc/src/Makefile > @@ -0,0 +1,19 @@ > +CC= cc > +CFLAGS= -O -Wall -Wstrict-prototypes > + > +PROGS= rtctest > + > +SRCS= rtctest.c > +OBJS= ${SRCS:.c=.o} > + > + > +all: $(PROGS) > + > +rtctest: $(OBJS) > + $(CC) $(LDFLAGS) -o rtctest $(OBJS) > + > +clean: > + -rm -f $(OBJS) > + > +clobber: clean > + -rm -f $(PROGS) > diff --git a/client/tests/rtc/src/rtctest.c b/client/tests/rtc/src/rtctest.c > new file mode 100644 > index 0000000..25b74af > --- /dev/null > +++ b/client/tests/rtc/src/rtctest.c > @@ -0,0 +1,261 @@ > +/* > + * Real Time Clock Driver Test/Example Program > + * > + * Compile with: > + * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest > + * > + * Copyright (C) 1996, Paul Gortmaker. > + * Copyright (C) 2010, Jason Wang <jasowang@xxxxxxxxxx> > + * > + * Released under the GNU General Public License, version 2, > + * included herein by reference. > + * > + */ > + > +#include <stdio.h> > +#include <linux/rtc.h> > +#include <sys/ioctl.h> > +#include <sys/time.h> > +#include <sys/types.h> > +#include <fcntl.h> > +#include <unistd.h> > +#include <stdlib.h> > +#include <errno.h> > + > + > +/* > + * This expects the new RTC class driver framework, working with > + * clocks that will often not be clones of what the PC-AT had. > + * Use the command line to specify another RTC if you need one. > + */ > +static const char default_rtc[] = "/dev/rtc0"; > +static int maxfreq = 64; > + > +int main(int argc, char **argv) > +{ > + int i, fd, retval, irqcount = 0; > + unsigned long tmp, data; > + struct rtc_time rtc_tm; > + const char *rtc = default_rtc; > + > + switch (argc) { > + case 3: > + maxfreq = atoi(argv[2]); > + case 2: > + rtc = argv[1]; > + /* FALLTHROUGH */ > + case 1: > + break; > + default: > + fprintf(stderr, "usage: rtctest [rtcdev] [maxfreq]\n"); > + return 1; > + } > + > + fd = open(rtc, O_RDONLY); > + > + if (fd == -1) { > + perror(rtc); > + exit(errno); > + } > + > + fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); > + > + /* Turn on update interrupts (one per second) */ > + retval = ioctl(fd, RTC_UIE_ON, 0); > + if (retval == -1) { > + if (errno == ENOTTY) { > + fprintf(stderr, > + "\n...Update IRQs not supported.\n"); > + goto test_READ; > + } > + perror("RTC_UIE_ON ioctl"); > + exit(errno); > + } > + > + fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", > + rtc); > + fflush(stderr); > + for (i=1; i<6; i++) { > + /* This read will block */ > + retval = read(fd, &data, sizeof(unsigned long)); > + if (retval == -1) { > + perror("read"); > + exit(errno); > + } > + fprintf(stderr, " %d",i); > + fflush(stderr); > + irqcount++; > + } > + > + fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); > + fflush(stderr); > + for (i=1; i<6; i++) { > + struct timeval tv = {5, 0}; /* 5 second timeout on select */ > + fd_set readfds; > + > + FD_ZERO(&readfds); > + FD_SET(fd, &readfds); > + /* The select will wait until an RTC interrupt happens. */ > + retval = select(fd+1, &readfds, NULL, NULL, &tv); > + if (retval == -1) { > + perror("select"); > + exit(errno); > + } > + /* This read won't block unlike the select-less case above. */ > + retval = read(fd, &data, sizeof(unsigned long)); > + if (retval == -1) { > + perror("read"); > + exit(errno); > + } > + fprintf(stderr, " %d",i); > + fflush(stderr); > + irqcount++; > + } > + > + /* Turn off update interrupts */ > + retval = ioctl(fd, RTC_UIE_OFF, 0); > + if (retval == -1) { > + perror("RTC_UIE_OFF ioctl"); > + exit(errno); > + } > + > +test_READ: > + /* Read the RTC time/date */ > + retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); > + if (retval == -1) { > + perror("RTC_RD_TIME ioctl"); > + exit(errno); > + } > + > + fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", > + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, > + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); > + > + /* Set the alarm to 5 sec in the future, and check for rollover */ > + rtc_tm.tm_sec += 5; > + if (rtc_tm.tm_sec >= 60) { > + rtc_tm.tm_sec %= 60; > + rtc_tm.tm_min++; > + } > + if (rtc_tm.tm_min == 60) { > + rtc_tm.tm_min = 0; > + rtc_tm.tm_hour++; > + } > + if (rtc_tm.tm_hour == 24) > + rtc_tm.tm_hour = 0; > + > + retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); > + if (retval == -1) { > + if (errno == ENOTTY) { > + fprintf(stderr, > + "\n...Alarm IRQs not supported.\n"); > + goto test_PIE; > + } > + perror("RTC_ALM_SET ioctl"); > + exit(errno); > + } > + > + /* Read the current alarm settings */ > + retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); > + if (retval == -1) { > + perror("RTC_ALM_READ ioctl"); > + exit(errno); > + } > + > + fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", > + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); > + > + /* Enable alarm interrupts */ > + retval = ioctl(fd, RTC_AIE_ON, 0); > + if (retval == -1) { > + perror("RTC_AIE_ON ioctl"); > + exit(errno); > + } > + > + fprintf(stderr, "Waiting 5 seconds for alarm..."); > + fflush(stderr); > + /* This blocks until the alarm ring causes an interrupt */ > + retval = read(fd, &data, sizeof(unsigned long)); > + if (retval == -1) { > + perror("read"); > + exit(errno); > + } > + irqcount++; > + fprintf(stderr, " okay. Alarm rang.\n"); > + > + /* Disable alarm interrupts */ > + retval = ioctl(fd, RTC_AIE_OFF, 0); > + if (retval == -1) { > + perror("RTC_AIE_OFF ioctl"); > + exit(errno); > + } > + > +test_PIE: > + /* Read periodic IRQ rate */ > + retval = ioctl(fd, RTC_IRQP_READ, &tmp); > + if (retval == -1) { > + /* not all RTCs support periodic IRQs */ > + if (errno == ENOTTY) { > + fprintf(stderr, "\nNo periodic IRQ support\n"); > + goto done; > + } > + perror("RTC_IRQP_READ ioctl"); > + exit(errno); > + } > + fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); > + > + fprintf(stderr, "Counting 20 interrupts at:"); > + fflush(stderr); > + > + /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ > + for (tmp=2; tmp<=maxfreq; tmp*=2) { > + > + retval = ioctl(fd, RTC_IRQP_SET, tmp); > + if (retval == -1) { > + /* not all RTCs can change their periodic IRQ rate */ > + if (errno == ENOTTY) { > + fprintf(stderr, > + "\n...Periodic IRQ rate is fixed\n"); > + goto done; > + } > + perror("RTC_IRQP_SET ioctl"); > + exit(errno); > + } > + > + fprintf(stderr, "\n%ldHz:\t", tmp); > + fflush(stderr); > + > + /* Enable periodic interrupts */ > + retval = ioctl(fd, RTC_PIE_ON, 0); > + if (retval == -1) { > + perror("RTC_PIE_ON ioctl"); > + exit(errno); > + } > + > + for (i=1; i<21; i++) { > + /* This blocks */ > + retval = read(fd, &data, sizeof(unsigned long)); > + if (retval == -1) { > + perror("read"); > + exit(errno); > + } > + fprintf(stderr, " %d",i); > + fflush(stderr); > + irqcount++; > + } > + > + /* Disable periodic interrupts */ > + retval = ioctl(fd, RTC_PIE_OFF, 0); > + if (retval == -1) { > + perror("RTC_PIE_OFF ioctl"); > + exit(errno); > + } > + } > + > +done: > + fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); > + > + close(fd); > + > + return 0; > +} > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html