Commit 55a248c7 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Linus Torvalds

[PATCH] Genrtc updates

Genrtc: Sync generic RTC driver with 2.4.x.
parent 50d21c5c
/* /*
* Real Time Clock interface for q40 and other m68k machines * Real Time Clock interface for
* - q40 and other m68k machines,
* - HP PARISC machines
* - PowerPC machines
* emulate some RTC irq capabilities in software * emulate some RTC irq capabilities in software
* *
* Copyright (C) 1999 Richard Zidlicky * Copyright (C) 1999 Richard Zidlicky
...@@ -13,7 +16,7 @@ ...@@ -13,7 +16,7 @@
* pseudo-file for status information. * pseudo-file for status information.
* *
* The ioctls can be used to set the interrupt behaviour where * The ioctls can be used to set the interrupt behaviour where
* supported. * supported.
* *
* The /dev/rtc interface will block on reads until an interrupt * The /dev/rtc interface will block on reads until an interrupt
* has been received. If a RTC interrupt has already happened, * has been received. If a RTC interrupt has already happened,
...@@ -34,9 +37,10 @@ ...@@ -34,9 +37,10 @@
* 1.04 removed useless timer code rz@linux-m68k.org * 1.04 removed useless timer code rz@linux-m68k.org
* 1.05 portable RTC_UIE emulation rz@linux-m68k.org * 1.05 portable RTC_UIE emulation rz@linux-m68k.org
* 1.06 set_rtc_time can return an error trini@kernel.crashing.org * 1.06 set_rtc_time can return an error trini@kernel.crashing.org
* 1.07 ported to HP PARISC (hppa) Helge Deller <deller@gmx.de>
*/ */
#define RTC_VERSION "1.06" #define RTC_VERSION "1.07"
#include <linux/module.h> #include <linux/module.h>
#include <linux/config.h> #include <linux/config.h>
...@@ -63,20 +67,17 @@ ...@@ -63,20 +67,17 @@
static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait); static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait);
static int gen_rtc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
/* /*
* Bits in gen_rtc_status. * Bits in gen_rtc_status.
*/ */
#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */
unsigned char gen_rtc_status; /* bitmapped status byte. */ static unsigned char gen_rtc_status; /* bitmapped status byte. */
unsigned long gen_rtc_irq_data; /* our output to the world */ static unsigned long gen_rtc_irq_data; /* our output to the world */
/* months start at 0 now */ /* months start at 0 now */
unsigned char days_in_mo[] = static unsigned char days_in_mo[] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int irq_active; static int irq_active;
...@@ -89,18 +90,20 @@ static unsigned int oldsecs; ...@@ -89,18 +90,20 @@ static unsigned int oldsecs;
static int lostint; static int lostint;
static int tt_exp; static int tt_exp;
void gen_rtc_timer(unsigned long data); static void gen_rtc_timer(unsigned long data);
static volatile int stask_active; /* schedule_work */ static volatile int stask_active; /* schedule_work */
static volatile int ttask_active; /* timer_task */ static volatile int ttask_active; /* timer_task */
static int stop_rtc_timers; /* don't requeue tasks */ static int stop_rtc_timers; /* don't requeue tasks */
static spinlock_t gen_rtc_lock = SPIN_LOCK_UNLOCKED; static spinlock_t gen_rtc_lock = SPIN_LOCK_UNLOCKED;
static void gen_rtc_interrupt(unsigned long arg);
/* /*
* Routine to poll RTC seconds field for change as often as possible, * Routine to poll RTC seconds field for change as often as possible,
* after first RTC_UIE use timer to reduce polling * after first RTC_UIE use timer to reduce polling
*/ */
void genrtc_troutine(void *data) static void genrtc_troutine(void *data)
{ {
unsigned int tmp = get_rtc_ss(); unsigned int tmp = get_rtc_ss();
...@@ -124,7 +127,7 @@ void genrtc_troutine(void *data) ...@@ -124,7 +127,7 @@ void genrtc_troutine(void *data)
stask_active = 0; stask_active = 0;
} }
void gen_rtc_timer(unsigned long data) static void gen_rtc_timer(unsigned long data)
{ {
lostint = get_rtc_ss() - oldsecs ; lostint = get_rtc_ss() - oldsecs ;
if (lostint<0) if (lostint<0)
...@@ -145,7 +148,7 @@ void gen_rtc_timer(unsigned long data) ...@@ -145,7 +148,7 @@ void gen_rtc_timer(unsigned long data)
* from some routine that periodically (eg 100HZ) monitors * from some routine that periodically (eg 100HZ) monitors
* whether RTC_SECS changed * whether RTC_SECS changed
*/ */
void gen_rtc_interrupt(unsigned long arg) static void gen_rtc_interrupt(unsigned long arg)
{ {
/* We store the status in the low byte and the number of /* We store the status in the low byte and the number of
* interrupts received since the last read in the remainder * interrupts received since the last read in the remainder
...@@ -175,7 +178,7 @@ static ssize_t gen_rtc_read(struct file *file, char *buf, ...@@ -175,7 +178,7 @@ static ssize_t gen_rtc_read(struct file *file, char *buf,
unsigned long data; unsigned long data;
ssize_t retval; ssize_t retval;
if (count != sizeof (unsigned int) && count != sizeof (unsigned long)) if (count != sizeof (unsigned int) && count != sizeof (unsigned long))
return -EINVAL; return -EINVAL;
if (file->f_flags & O_NONBLOCK && !gen_rtc_irq_data) if (file->f_flags & O_NONBLOCK && !gen_rtc_irq_data)
...@@ -385,24 +388,24 @@ static int gen_rtc_read_proc(char *page, char **start, off_t off, ...@@ -385,24 +388,24 @@ static int gen_rtc_read_proc(char *page, char **start, off_t off,
*/ */
static struct file_operations gen_rtc_fops = { static struct file_operations gen_rtc_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_GEN_RTC_X #ifdef CONFIG_GEN_RTC_X
.read = gen_rtc_read, .read = gen_rtc_read,
.poll = gen_rtc_poll, .poll = gen_rtc_poll,
#endif #endif
.ioctl = gen_rtc_ioctl, .ioctl = gen_rtc_ioctl,
.open = gen_rtc_open, .open = gen_rtc_open,
.release = gen_rtc_release .release = gen_rtc_release,
}; };
static struct miscdevice rtc_gen_dev = static struct miscdevice rtc_gen_dev =
{ {
RTC_MINOR, .minor = RTC_MINOR,
"rtc", .name = "rtc",
&gen_rtc_fops .fops = &gen_rtc_fops,
}; };
int __init rtc_generic_init(void) static int __init rtc_generic_init(void)
{ {
int retval; int retval;
...@@ -436,16 +439,18 @@ module_exit(rtc_generic_exit); ...@@ -436,16 +439,18 @@ module_exit(rtc_generic_exit);
* Info exported via "/proc/rtc". * Info exported via "/proc/rtc".
*/ */
int gen_rtc_proc_output(char *buf) #ifdef CONFIG_PROC_FS
static int gen_rtc_proc_output(char *buf)
{ {
char *p; char *p;
struct rtc_time tm; struct rtc_time tm;
unsigned tmp; unsigned int flags;
struct rtc_pll_info pll; struct rtc_pll_info pll;
p = buf; p = buf;
get_rtc_time(&tm); flags = get_rtc_time(&tm);
p += sprintf(p, p += sprintf(p,
"rtc_time\t: %02d:%02d:%02d\n" "rtc_time\t: %02d:%02d:%02d\n"
...@@ -454,7 +459,7 @@ int gen_rtc_proc_output(char *buf) ...@@ -454,7 +459,7 @@ int gen_rtc_proc_output(char *buf)
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1900); tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1900);
tm.tm_hour=0;tm.tm_min=0;tm.tm_sec=0; tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
p += sprintf(p, "alarm\t\t: "); p += sprintf(p, "alarm\t\t: ");
if (tm.tm_hour <= 24) if (tm.tm_hour <= 24)
...@@ -472,7 +477,6 @@ int gen_rtc_proc_output(char *buf) ...@@ -472,7 +477,6 @@ int gen_rtc_proc_output(char *buf)
else else
p += sprintf(p, "**\n"); p += sprintf(p, "**\n");
tmp= RTC_24H ;
p += sprintf(p, p += sprintf(p,
"DST_enable\t: %s\n" "DST_enable\t: %s\n"
"BCD\t\t: %s\n" "BCD\t\t: %s\n"
...@@ -483,15 +487,15 @@ int gen_rtc_proc_output(char *buf) ...@@ -483,15 +487,15 @@ int gen_rtc_proc_output(char *buf)
"periodic_IRQ\t: %s\n" "periodic_IRQ\t: %s\n"
"periodic_freq\t: %ld\n" "periodic_freq\t: %ld\n"
"batt_status\t: %s\n", "batt_status\t: %s\n",
(tmp & RTC_DST_EN) ? "yes" : "no", (flags & RTC_DST_EN) ? "yes" : "no",
(tmp & RTC_DM_BINARY) ? "no" : "yes", (flags & RTC_DM_BINARY) ? "no" : "yes",
(tmp & RTC_24H) ? "yes" : "no", (flags & RTC_24H) ? "yes" : "no",
(tmp & RTC_SQWE) ? "yes" : "no", (flags & RTC_SQWE) ? "yes" : "no",
(tmp & RTC_AIE) ? "yes" : "no", (flags & RTC_AIE) ? "yes" : "no",
irq_active ? "yes" : "no", irq_active ? "yes" : "no",
(tmp & RTC_PIE) ? "yes" : "no", (flags & RTC_PIE) ? "yes" : "no",
0L /* freq */, 0L /* freq */,
"okay" ); (flags & RTC_BATT_BAD) ? "bad" : "okay");
if (!get_rtc_pll(&pll)) if (!get_rtc_pll(&pll))
p += sprintf(p, p += sprintf(p,
"PLL adjustment\t: %d\n" "PLL adjustment\t: %d\n"
...@@ -506,7 +510,7 @@ int gen_rtc_proc_output(char *buf) ...@@ -506,7 +510,7 @@ int gen_rtc_proc_output(char *buf)
pll.pll_posmult, pll.pll_posmult,
pll.pll_negmult, pll.pll_negmult,
pll.pll_clock); pll.pll_clock);
return p - buf; return p - buf;
} }
static int gen_rtc_read_proc(char *page, char **start, off_t off, static int gen_rtc_read_proc(char *page, char **start, off_t off,
...@@ -521,6 +525,9 @@ static int gen_rtc_read_proc(char *page, char **start, off_t off, ...@@ -521,6 +525,9 @@ static int gen_rtc_read_proc(char *page, char **start, off_t off,
return len; return len;
} }
#endif /* CONFIG_PROC_FS */
MODULE_AUTHOR("Richard Zidlicky"); MODULE_AUTHOR("Richard Zidlicky");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -14,23 +14,21 @@ ...@@ -14,23 +14,21 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/rtc.h> #include <linux/rtc.h>
#include <asm/errno.h>
#include <asm/machdep.h> #include <asm/machdep.h>
/* a few implementation details for the emulation : */
#define RTC_PIE 0x40 /* periodic interrupt enable */ #define RTC_PIE 0x40 /* periodic interrupt enable */
#define RTC_AIE 0x20 /* alarm interrupt enable */ #define RTC_AIE 0x20 /* alarm interrupt enable */
#define RTC_UIE 0x10 /* update-finished interrupt enable */ #define RTC_UIE 0x10 /* update-finished interrupt enable */
extern void gen_rtc_interrupt(unsigned long);
/* some dummy definitions */ /* some dummy definitions */
#define RTC_BATT_BAD 0x100 /* battery bad */
#define RTC_SQWE 0x08 /* enable square-wave output */ #define RTC_SQWE 0x08 /* enable square-wave output */
#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
static inline void get_rtc_time(struct rtc_time *time) static inline unsigned int get_rtc_time(struct rtc_time *time)
{ {
/* /*
* Only the values that we read from the RTC are set. We leave * Only the values that we read from the RTC are set. We leave
...@@ -39,6 +37,7 @@ static inline void get_rtc_time(struct rtc_time *time) ...@@ -39,6 +37,7 @@ static inline void get_rtc_time(struct rtc_time *time)
* by the RTC when initially set to a non-zero value. * by the RTC when initially set to a non-zero value.
*/ */
mach_hwclk(0, time); mach_hwclk(0, time);
return RTC_24H;
} }
static inline int set_rtc_time(struct rtc_time *time) static inline int set_rtc_time(struct rtc_time *time)
...@@ -52,7 +51,7 @@ static inline unsigned int get_rtc_ss(void) ...@@ -52,7 +51,7 @@ static inline unsigned int get_rtc_ss(void)
return mach_get_ss(); return mach_get_ss();
else{ else{
struct rtc_time h; struct rtc_time h;
get_rtc_time(&h); get_rtc_time(&h);
return h.tm_sec; return h.tm_sec;
} }
...@@ -72,7 +71,6 @@ static inline int set_rtc_pll(struct rtc_pll_info *pll) ...@@ -72,7 +71,6 @@ static inline int set_rtc_pll(struct rtc_pll_info *pll)
else else
return -EINVAL; return -EINVAL;
} }
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM__RTC_H */ #endif /* _ASM__RTC_H */
...@@ -63,7 +63,7 @@ struct rtc_pll_info { ...@@ -63,7 +63,7 @@ struct rtc_pll_info {
}; };
/* /*
* ioctl calls that are permitted to the /dev/rtc interface, if * ioctl calls that are permitted to the /dev/rtc interface, if
* any of the RTC drivers are enabled. * any of the RTC drivers are enabled.
*/ */
...@@ -87,6 +87,7 @@ struct rtc_pll_info { ...@@ -87,6 +87,7 @@ struct rtc_pll_info {
#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/ #define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/ #define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ #define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment