Subject: [RFC] generic MIPS RTC driver

From: Jun Sun <[email-masked]>
Date: Sat, 10 Nov 2001 23:17:46 -0800

For many MIPS boards that start to use CONFIG_NEW_TIME_C, two rtc operations
are implemented, rtc_get_time() and rtc_set_time().

It is possible to write a simple generic RTC driver that is based on
these two ops and can do simple RTC read&write ops.  

In other words, with such a driver, once you implemented rtc_get_time() 
and rtc_set_time(), which is required by the kernel anyway, you will 
automatically get a free /dev/rtc/ driver.

This is the idea behind the generic MIPS rtc driver.  See the patch below.

Right now the feature is rather limited, due to the thin abstraction
we are having with rtc ops.  But apparently the implementation is good
enough to make hwclock program happy.

Any comments?

Jun

/*
 *      A simple generic Real Time Clock interface for Linux/MIPS
 *
 *      Copyright (C) 1996 Paul Gortmaker
 *
 *      Copyright (C) 2001 Monta Vista Software
 *      Author Jun Sun, [email-masked] or [email-masked]
 *
 *      This is a simple generic RTC driver for MIPS boards configured 
 *      with CONFIG_NEW_TIME_C.  For now, it makes use of the two
 *      abstract kernel RTC functions introduced in include/asm-mips/time.h:
 *
 *              extern unsigned long (*rtc_get_time)(void);
 *              extern int (*rtc_set_time)(unsigned long);
 *
 *      It uses the same protocol as the original drivers/char/rtc.c driver,
 *      but only implements two ioctls: RTC_RD_TIME and RTC_SET_TIME.
 *
 *      TODO :
 *
 *      1. we can extend the null rtc ops defined in arch/mips/time.c to
 *         at least record the elapsed time (by recording/checking jiffies)
 *         This way RTC_RD_TIME and RTC_SET_TIME will make more sense.
 *         (Maybe not.  A machine without a real RTC is broken anymore.
 *         Just a thought.)
 *
 *      2. If we make use of timer bh, we can emulate many RTC functions
 *         such as RTC alarm interrupt, periodic interrupts, etc.
 *
 *      3. It is possible to extend the kernel RTC abstractions to more
 *         than two functions, so that perhaps we can implement more
 *         full-featured RTC driver and also have a better abstraction
 *         to support more RTC hardware than the original RTC driver.
 *         It needs to be done very carefully.
 *
 * Change Log :
 *      v1.0    - [jsun] initial version
 */

diff -Nru linux/Documentation/Configure.help.orig linux/Documentation/Configure.help
--- linux/Documentation/Configure.help.orig	Sat Nov 10 18:48:51 2001
+++ linux/Documentation/Configure.help	Sat Nov 10 22:58:23 2001
@@ -15163,6 +15163,17 @@
 #EFI Real Time Clock Services
 #CONFIG_EFI_RTC
 
+Generic MIPS RTC Support
+CONFIG_MIPS_RTC
+
+  If your machine is a MIPS machine, this option provides a simple,
+  generic RTC driver for /dev/rtc device.  It only implements two IOCTL 
+  operations of the standard PC RTC driver: RTC_RD_TIME and RTC_SET_TIME.
+  It is sufficient to run hwclock program. 
+
+  You should say Y here if there is no machine-specific RTC driver for your
+  MIPS machine but you do want a simple RTC driver for your RTC device.
+
 Tadpole ANA H8 Support
 CONFIG_H8
   The Hitachi H8/337 is a microcontroller used to deal with the power
diff -Nru linux/drivers/char/Config.in.orig linux/drivers/char/Config.in
--- linux/drivers/char/Config.in.orig	Sat Nov 10 18:49:31 2001
+++ linux/drivers/char/Config.in	Sat Nov 10 22:48:27 2001
@@ -194,6 +194,9 @@
 if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then
    bool 'Tadpole ANA H8 Support'  CONFIG_H8
 fi
+if [ "$CONFIG_MIPS" = "y" -a "$CONFIG_NEW_TIME_C" = "y" ]; then
+   tristate 'Generic MIPS RTC Support' CONFIG_MIPS_RTC
+fi
 
 tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
 tristate 'Siemens R3964 line discipline' CONFIG_R3964
diff -Nru linux/drivers/char/Makefile.orig linux/drivers/char/Makefile
--- linux/drivers/char/Makefile.orig	Sat Nov 10 18:49:31 2001
+++ linux/drivers/char/Makefile	Sat Nov 10 21:54:00 2001
@@ -194,6 +194,7 @@
 obj-$(CONFIG_PC110_PAD) += pc110pad.o
 obj-$(CONFIG_RTC) += rtc.o
 obj-$(CONFIG_EFI_RTC) += efirtc.o
+obj-$(CONFIG_MIPS_RTC) += mips_rtc.o
 ifeq ($(CONFIG_PPC),)
   obj-$(CONFIG_NVRAM) += nvram.o
 endif
diff -Nru linux/drivers/char/mips_rtc.c.orig linux/drivers/char/mips_rtc.c
--- linux/drivers/char/mips_rtc.c.orig	Sat Nov 10 21:03:02 2001
+++ linux/drivers/char/mips_rtc.c	Sat Nov 10 23:10:39 2001
@@ -0,0 +1,221 @@
+/*
+ *	A simple generic Real Time Clock interface for Linux/MIPS
+ *
+ *	Copyright (C) 1996 Paul Gortmaker
+ *
+ *	Copyright (C) 2001 Monta Vista Software
+ *	Author Jun Sun, [email-masked] or [email-masked]
+ *
+ *	This is a simple generic RTC driver for MIPS boards configured 
+ *	with CONFIG_NEW_TIME_C.  For now, it makes use of the two
+ *	abstract kernel RTC functions introduced in include/asm-mips/time.h:
+ *
+ *		extern unsigned long (*rtc_get_time)(void);
+ *		extern int (*rtc_set_time)(unsigned long);
+ *
+ *	It uses the same protocol as the original drivers/char/rtc.c driver,
+ *	but only implements two ioctls: RTC_RD_TIME and RTC_SET_TIME.
+ *
+ * 	TODO :
+ *
+ * 	1. we can extend the null rtc ops defined in arch/mips/time.c to
+ * 	   at least record the elapsed time (by recording/checking jiffies)
+ * 	   This way RTC_ALM_READ and RTC_ALM_SET will make more sense.
+ * 	   (Maybe not.  A machine without a real RTC is broken anymore.
+ * 	   Just a thought.)
+ *
+ * 	2. If we make use of timer bh, we can emulate many RTC functions
+ * 	   such as RTC alarm interrupt, periodic interrupts, etc.
+ *
+ * 	3. It is possible to extend the kernel RTC abstractions to more
+ * 	   than two functions, so that perhaps we can implement more
+ * 	   full-featured RTC driver and also have a better abstraction
+ * 	   to support more RTC hardware than the original RTC driver.
+ * 	   It needs to be done very carefully.
+ *
+ * Change Log :
+ * 	v1.0	- [jsun] initial version
+ */
+
+#define RTC_VERSION		"1.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+/*
+ * Check machine
+ */
+#if !defined(CONFIG_MIPS) || !defined(CONFIG_NEW_TIME_C)
+#error "This driver is for MIPS machines with CONFIG_NEW_TIME_C defined"
+#endif
+
+#include <asm/time.h>
+
+static unsigned long rtc_status = 0;	/* bitmapped status byte.       */
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+			 int count, int *eof, void *data);
+
+
+#define RTC_IS_OPEN             0x01	/* means /dev/rtc is in use     */
+
+static spinlock_t rtc_lock;
+
+static int
+rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg)
+{
+	struct rtc_time rtc_tm;
+	ulong curr_time;
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC  */
+		curr_time = rtc_get_time();
+		to_tm(curr_time, &rtc_tm);
+		rtc_tm.tm_year -= 1900;
+		return copy_to_user((void *) arg, &rtc_tm, sizeof(rtc_tm)) ? 
+			-EFAULT : 0;
+	case RTC_SET_TIME:	/* Set the RTC */
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm, 
+				   (struct rtc_time *) arg,
+		                   sizeof(struct rtc_time))) 
+			return -EFAULT;
+
+		curr_time = mktime(rtc_tm.tm_year + 1900,
+				   rtc_tm.tm_mon + 1, /* tm_mon starts from 0 */
+				   rtc_tm.tm_mday,
+				   rtc_tm.tm_hour,
+				   rtc_tm.tm_min, 
+				   rtc_tm.tm_sec);
+		return rtc_set_time(curr_time);
+	default:
+		return -EINVAL;
+	}
+}
+
+/* We use rtc_lock to protect against concurrent opens. So the BKL is not
+ * needed here. Or anywhere else in this driver. */
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	spin_lock_irq(&rtc_lock);
+
+	if (rtc_status & RTC_IS_OPEN) {
+		spin_unlock_irq(&rtc_lock);
+		return -EBUSY;
+	}
+
+	rtc_status |= RTC_IS_OPEN;
+
+	spin_unlock_irq(&rtc_lock);
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	spin_lock_irq(&rtc_lock);
+	rtc_status &= ~RTC_IS_OPEN;
+	spin_unlock_irq(&rtc_lock);
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	owner:THIS_MODULE,
+	llseek:no_llseek,
+	ioctl:rtc_ioctl,
+	open:rtc_open,
+	release:rtc_release,
+};
+
+static struct miscdevice rtc_dev = {
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+static int __init rtc_init(void)
+{
+
+	misc_register(&rtc_dev);
+	create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL);
+
+	printk(KERN_INFO "Generic MIPS RTC Driver v" RTC_VERSION "\n");
+
+	return 0;
+}
+
+static void __exit rtc_exit(void)
+{
+	remove_proc_entry("driver/rtc", NULL);
+	misc_deregister(&rtc_dev);
+
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
+EXPORT_NO_SYMBOLS;
+
+/*
+ *	Info exported via "/proc/driver/rtc".
+ */
+
+static int rtc_proc_output(char *buf)
+{
+	char *p;
+	struct rtc_time tm;
+	unsigned long curr_time;
+
+	curr_time = rtc_get_time();
+	to_tm(curr_time, &tm);
+
+	p = buf;
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+	p += sprintf(p,
+		     "rtc_time\t: %02d:%02d:%02d\n"
+		     "rtc_date\t: %04d-%02d-%02d\n"
+		     "rtc_epoch\t: %04lu\n",
+		     tm.tm_hour, tm.tm_min, tm.tm_sec,
+		     tm.tm_year, tm.tm_mon + 1, tm.tm_mday, 0L);
+
+	return p - buf;
+}
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+			 int count, int *eof, void *data)
+{
+	int len = rtc_proc_output(page);
+	if (len <= off + count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+	return len;
+}
+
+MODULE_AUTHOR("Jun Sun");
+MODULE_LICENSE("GPL");

---

From: Geert Uytterhoeven <[email-masked]>
Date: Sun, 11 Nov 2001 11:14:26 +0100 (MET)

> This is the idea behind the generic MIPS rtc driver.  See the patch below.

Oh no, don't tell me we now have (at least) _three_ of these floating around
:-)

  - On m68k, we have drivers/char/genrtc.c (not yet merged, check out CVS, see
    http://linux-m68k-cvs.apia.dhs.org/).
  - On PPC, we have drivers/macintosh/rtc.c.
  - On MIPS, we now have your drivers/char/mips_rtc.c.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email-masked]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

---

From: Atsushi Nemoto <[email-masked]>
Date: Mon, 12 Nov 2001 10:45:19 +0900 (JST)

>>>>> On Sat, 10 Nov 2001 23:17:46 -0800, Jun Sun <[email-masked]> said:
jsun> For many MIPS boards that start to use CONFIG_NEW_TIME_C, two
jsun> rtc operations are implemented, rtc_get_time() and
jsun> rtc_set_time().
jsun> It is possible to write a simple generic RTC driver that is
jsun> based on these two ops and can do simple RTC read&write ops.
...
jsun> This is the idea behind the generic MIPS rtc driver.  See the
jsun> patch below.
...
jsun> Any comments?

Good idea.  I hope cvs kernel import this patch.

I found two small things to fix.  to_tm function sets 1..12 value in
tm_mon field, so

1. in rtc_ioctl (case RTC_RD_TIME), subtracting 1 from rtc_tm.tm_mon
   is needed.

2. in rtc_proc_output, adding 1 to tm.tm_mon is not needed.

---
Atsushi Nemoto

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 12 Nov 2001 13:59:11 +0100 (MET)

>   - On MIPS, we now have your drivers/char/mips_rtc.c.

 Agreed, what's wrong with drivers/char/rtc.c?  It even works for the
DECstation which maps its RTC in an unusual (but nice) way -- it's just a
matter of initializing rtc_ops appropriately.  See arch/mips/dec/rtc-dec.c
for an example.

 Unless you use a non-MC146818 RTC, which you need to write a separate
driver for anyway. 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email-masked], PGP key available        +

---

From: Geert Uytterhoeven <[email-masked]>
Date: Mon, 12 Nov 2001 14:11:26 +0100 (MET)

>  Agreed, what's wrong with drivers/char/rtc.c?  It even works for the

It's for MC146818 RTCs only.

>  Unless you use a non-MC146818 RTC, which you need to write a separate

Yep, so that's why both m68k and PPC have common routines to read/write the
RTC, with a /dev/rtc-compatible abstraction on top of it.

Gr{oetje,eeting}s,

						Geert

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 12 Nov 2001 14:29:14 +0100 (MET)

> RTC, with a /dev/rtc-compatible abstraction on top of it.

 OK, then you need an RTC chipset-specific driver and not a CPU
architecture-specific one.  Otherwise we'll end with a zillion of similar
RTC drivers like we already have for LANCE and SCC chips.

---

From: Pete Popov <[email-masked]>
Date: 12 Nov 2001 08:14:39 -0800

> RTC drivers like we already have for LANCE and SCC chips. 

I agree.  We don't have arch specific network drivers so why have arch
specific rtc drivers.

Pete

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 10:19:54 -0800

> RTC, with a /dev/rtc-compatible abstraction on top of it.

Geert, what is the abstraction they used?

The /dev/rtc interface is highly influenced by MC146818 chip, which not all
RTC devices are alike.  The only fundamental thing in the driver is really the
read and write time.

If their abstraction is reasonable, perhaps they can all converge to a better,
more generic rtc interface.

Jun

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 10:26:36 -0800

> I agree.  We don't have arch specific network drivers so why have arch

Because we can have a free RTC driver working once you get kernel working.

Jun

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 10:24:35 -0800

"Maciej W. Rozycki" wrote:
> architecture-specific one. 

You *can* write a chip specific driver in addition to this generic one if you
want.  Presumably the chip-specific one provides more operations than just
read/write date.

> Otherwise we'll end with a zillion of similar

Don't quite understand this statement.

If everybody uses the generic rtc driver, there will be only one copy of it. 
It will prevent zillions copies of similar thing.

Note that hardware specifics are already abstracted by rtc_set_time() and
rtc_get_time() routines.  The generic RTC driver makes use of them and has no
RTC chip or machine dependent code.

Jun

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 12 Nov 2001 19:55:37 +0100 (MET)

> RTC devices are alike.  The only fundamental thing in the driver is really the

 You need only to keep the interface, which is:

static struct file_operations rtc_fops = {
	owner:		THIS_MODULE,
	llseek:		no_llseek,
	read:		rtc_read,
#if RTC_IRQ
	poll:		rtc_poll,
#endif
	ioctl:		rtc_ioctl,
	open:		rtc_open,
	release:	rtc_release,
	fasync:		rtc_fasync,
};

Of these you probably must only implement open() and ioctl() -- you may
provide others as hardware permits -- see how these functions are
implemented in drivers/char/rtc.c.  The interface is pretty generic, IMHO. 

> more generic rtc interface.

 Just implement the ioctls given hardware permits and return -EINVAL for
others.  Again, they are pretty generic: get/set the time, alarm, epoch,
disable/enable various interrupts, etc. -- see include/linux/rtc.h.  You
may propose additional ioctls if they would be useful for particular
hardware.

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 10:56:44 -0800

> Because we can have a free RTC driver working once you get kernel working.

Actually there is a longer answer with a little bit of the background info.

Kernel needs to know about the real calendar time when it boots up.  And
optionally it may write to RTC (based on the assumption that kernel timer is
more accurate than RTC clock).  So it already has abstraction, one form or
another, to do RTC read/write.

Based on these abstractons you can provide a hardware-independent RTC driver,
with RTC read/write operations.

Before CONFIG_NEW_TIME_C is introduced, each MIPS board has its own time
service routine, which means, even if RTC driver wants to utilize the
abstraction, it will be only for that board only.

After CONFIG_NEW_TIME_C is introduced, that RTC abstract becomes MIPS-common. 
Therefore, we can afford a MIPS-common generic RTC driver.

If that abstraction ever becomes Linux-common code, then the generic RTC
driver will essentially be a Linux-common, device-indpendent driver.

For most MIPS machine, we need /dev/rtc to merely set time and read time.  The
generic driver should suffice.  Otherwire, you can wirte a complete one for a
specific board or a specific chip.

Jun

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Mon, 12 Nov 2001 20:04:17 +0100 (MET)

> want.  Presumably the chip-specific one provides more operations than just

 Then why make this driver MIPS-specific?

> Don't quite understand this statement.

 This assumed you've meant an MC146818 RTC that already has a driver for
certain (but possibly not all) configurations.  Since you haven't -- just
forget it.

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 11:13:51 -0800

> may propose additional ioctls if they would be useful for particular

Basically agree.

Maybe the only thing really missing is a formal way to determine and report
the capability of the driver, rather through checking the return value being
-EINVAL.

I guess my original question to Geert is more on the abstraction of the RTC
hardware routines, especially anything beyond rtc_read_time() and
rt_write_time().

Jun

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 11:21:30 -0800

>  Then why make this driver MIPS-specific?

I suppose one of my previous replies should answer this.  Let me know if it
does not.

Jun

---

From: Jun Sun <[email-masked]>
Date: Mon, 12 Nov 2001 11:26:25 -0800

> 2. in rtc_proc_output, adding 1 to tm.tm_mon is not needed.

Good eye for spotting this. :-)

It turned out that tm_mon in rtc_time struct really should start from 0 to 11
(by definition).  So there is a bug in to_tm().  I sent a patch to Ralf and I
think he applied already.

Jun

---

From: Geert Uytterhoeven <[email-masked]>
Date: Mon, 12 Nov 2001 21:02:26 +0100 (MET)

> Geert, what is the abstraction they used?

At first sight, we only use get_rtc_time() and mach_hwclk().

> more generic rtc interface.

Check out the following files from the m68k CVS tree (see
http://linux-m68k-cvs.apia.dhs.org/):

  - drivers/char/genrtc.c
  - include/asm-m68k/machdep.h
  - include/asm-m68k/rtc.h

On PPC, they have something similar.

Gr{oetje,eeting}s,

						Geert

---

From: Roman Zippel <[email-masked]>
Date: Mon, 12 Nov 2001 21:54:55 +0100

Hi,

> At first sight, we only use get_rtc_time() and mach_hwclk().

Over the weekend I changed it into set_rtc_time()/get_rtc_time(), which
are now defined in <asm/rtc.h>, so mach_hwclk() is gone in the generic
part.
Another feature is the emulation of the timer interrupt, although I have
no idea which program is using this. Richard?

bye, Roman

---

From: Tom Rini <[email-masked]>
Date: Mon, 12 Nov 2001 14:51:14 -0700

> with RTC read/write operations.

Right.

> Therefore, we can afford a MIPS-common generic RTC driver.

No.  This sounds _exactly_ like the PPC driver. What we need to do, and
what I intend to do in 2.5 is make this a bit more generic so thatr any
arch can fill out some infos and say we read like this, we write like
that and that's that.

> driver will essentially be a Linux-common, device-indpendent driver.

Yeap.  I wanna do this in 2.5.

> specific board or a specific chip.

The 'rtc' driver in drivers/char does read, write, some ioctls and a
/proc bit.  We can make this a bit more 'generic'

-- 
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

---

From: Tom Rini <[email-masked]>
Date: Mon, 12 Nov 2001 18:31:58 -0700

> are now defined in <asm/rtc.h>, so mach_hwclk() is gone in the generic

Could you please post a copy of this?  I wanna go and try and get the
rest of the PPC world going on it, if you didn't do that already.

---

From: Geert Uytterhoeven <[email-masked]>
Date: Tue, 13 Nov 2001 07:20:51 +0100 (MET)

> rest of the PPC world going on it, if you didn't do that already.

http://linux-m68k-cvs.apia.dhs.org/

Gr{oetje,eeting}s,

						Geert

---

From: Richard Zidlicky <[email-masked]>
Date: Tue, 13 Nov 2001 14:42:40 +0100

On Mon, Nov 12, 2001 at 09:54:55PM +0100, Roman Zippel wrote:
> no idea which program is using this.

hwclock and a bunch of less known porgrams like chrony. 
Where the interrupt can be generated its a clear win, otherwise
it might be more reasonable to return EINVAL instead of trying
to emulate it - presumably hwclock can use some fallback method.

Btw the interrupt need not to be hardware, for the Q40 I test 
a rtc register once per jiffie and generate a "soft interrupt".
It could be done generic at least for m68k.

Bye
Richard

---

From: Tom Rini <[email-masked]>
Date: Tue, 13 Nov 2001 07:44:24 -0700

> http://linux-m68k-cvs.apia.dhs.org/

That's the non-generic m68k version tho, yes?  Or did Roman do it in
that tree too?

---

From: Geert Uytterhoeven <[email-masked]>
Date: Tue, 13 Nov 2001 15:47:53 +0100 (MET)

> That's the non-generic m68k version tho, yes?  Or did Roman do it in

That's the real one. On Q40/Q60 it provides some additional features, though.

Gr{oetje,eeting}s,

						Geert

---

From: Roman Zippel <[email-masked]>
Date: Tue, 13 Nov 2001 16:30:24 +0100 (CET)

Hi,

> That's the non-generic m68k version tho, yes?  Or did Roman do it in

That version is even more recent than the one currently in the APUS
repository. :)
But I tested it also under APUS, so you only need to provide
[gs]et_rtc_time and it should work.

bye, Roman

---

From: Roman Zippel <[email-masked]>
Date: Tue, 13 Nov 2001 16:32:42 +0100 (CET)

Hi,

> hwclock and a bunch of less known porgrams like chrony.

I was playing with chrony, but it was unable to adjust the time, last
weekend I switched back to ntp and that works better.

bye, Roman

---

From: Jun Sun <[email-masked]>
Date: Tue, 13 Nov 2001 09:58:45 -0800

> It could be done generic at least for m68k.

I have written an experiemntal ptimer driver to do just this and potential
more.  Such a device is useful for real-time programming (e.g., when you try
to implement a periodic user task).

See http://linux.junsun.net/realtime-linux/preemption-test

The driver is architecture independent (i.e., linux-common code)

Due to the different programming needs behind periodic timers (or user-level
timer) and RTC operations, my vote for future work is to leave them as two
separate drivers.  To me, RTC is really just to read/write RTC clock.

Jun

---

From: Richard Zidlicky <[email-masked]>
Date: Wed, 14 Nov 2001 10:46:55 +0100

> weekend I switched back to ntp and that works better.

some years ago chrony was the reason I wrote the Q40 rtc driver.
It didn't work very well for me either, but the rtc driver was
very useful in the meantime :)

Bye
Richard

---

From: Richard Zidlicky <[email-masked]>
Date: Wed, 14 Nov 2001 11:08:42 +0100

> separate drivers.  To me, RTC is really just to read/write RTC clock.

RTC_UIE is needed (or at least very useful) to set the clock, so it belongs 
into a rtc driver if it can be implemented. General purpose timers are
different story, btw what is wrong with setitimer that you have chosen 
to implement an additional driver for it?

Richard

---

From: Jun Sun <[email-masked]>
Date: Thu, 15 Nov 2001 09:41:13 -0800

> to implement an additional driver for it?

Easy of implmentation and more features.

Here is the pseudo code to do a real-time periodic task with /dev/ptimer:

void periodic_task(void)
{
	fd=open("/dev/ptimer", O_RDONLY);
	ioctl(fd, PTIMER_SET_PERIOD, PERIOD);
	ioctl(fd, PTIMER_SET_PHASE, PHASE);
	
	/* become realtime process */
	start_realtime();

	for(;;) {
		/* read won't return until next instance release point */
		read(fd, &count, sizeof(count));

		/* do the job */
		...
	}
}

Anybody who has used setitimer() would konw this is even simpler than the
setup of itimer, let alone with itimer you still need to deal with SIGALRM
signals plus some multi-thread signal handling considerations.

On the feature side, ptimer offers the exact control of phase.  For example,
you can have two tasks with period of 100ms, with one starting *exactly* at
time t and the other starting *exactly* at t+50 ms later.

Some unimplemented features allow you to control the behavior when missing
deadlines.

Jun