Commit 6a32f36f authored by Russell King's avatar Russell King

[ARM] Ensure that /proc/uptime returns sensible figures.

When we set xtime at boot from the RTC, we weren't setting the
monotonic time offset.  This had the effect of making the uptime
rather large.

We get around this problem by using the do_settimeofday() to set
the current time.  do_settimeofday() knows about this issue, and
will apply the appropriate correction to the monotonic time offset
for us.
parent 491e2425
...@@ -40,6 +40,7 @@ static unsigned long clps711x_gettimeoffset(void) ...@@ -40,6 +40,7 @@ static unsigned long clps711x_gettimeoffset(void)
void __init clps711x_setup_timer(void) void __init clps711x_setup_timer(void)
{ {
struct timespec tv;
unsigned int syscon; unsigned int syscon;
gettimeoffset = clps711x_gettimeoffset; gettimeoffset = clps711x_gettimeoffset;
...@@ -50,5 +51,7 @@ void __init clps711x_setup_timer(void) ...@@ -50,5 +51,7 @@ void __init clps711x_setup_timer(void)
clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
xtime.tv_sec = clps_readl(RTCDR); tv.tv_nsec = 0;
tv.tv_sec = clps_readl(RTCDR);
do_settimeofday(&tv);
} }
...@@ -280,13 +280,15 @@ static int ioc_client_reg(struct i2c_client *client) ...@@ -280,13 +280,15 @@ static int ioc_client_reg(struct i2c_client *client)
client->addr == 0x50) { client->addr == 0x50) {
struct rtc_tm rtctm; struct rtc_tm rtctm;
unsigned int year; unsigned int year;
struct timespec tv;
rtc_client = client; rtc_client = client;
get_rtc_time(&rtctm, &year); get_rtc_time(&rtctm, &year);
xtime.tv_nsec = rtctm.cs * 10000000; tv.tv_nsec = rtctm.cs * 10000000;
xtime.tv_sec = mktime(year, rtctm.mon, rtctm.mday, tv.tv_sec = mktime(year, rtctm.mon, rtctm.mday,
rtctm.hours, rtctm.mins, rtctm.secs); rtctm.hours, rtctm.mins, rtctm.secs);
do_settimeofday(&tv);
set_rtc = k_set_rtc_time; set_rtc = k_set_rtc_time;
} }
......
...@@ -243,6 +243,7 @@ void __init time_init(void) ...@@ -243,6 +243,7 @@ void __init time_init(void)
if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
CMOS_READ(RTC_REG_B) == reg_b) { CMOS_READ(RTC_REG_B) == reg_b) {
struct timespec tv;
/* /*
* We have a RTC. Check the battery * We have a RTC. Check the battery
...@@ -250,7 +251,9 @@ void __init time_init(void) ...@@ -250,7 +251,9 @@ void __init time_init(void)
if ((reg_d & 0x80) == 0) if ((reg_d & 0x80) == 0)
printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
xtime.tv_sec = get_isa_cmos_time(); tv.tv_nsec = 0;
tv.tv_sec = get_isa_cmos_time();
do_settimeofday(&tv);
set_rtc = set_isa_cmos_time; set_rtc = set_isa_cmos_time;
} else } else
rtc_base = 0; rtc_base = 0;
......
...@@ -73,9 +73,15 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -73,9 +73,15 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
void __init time_init(void) void __init time_init(void)
{ {
struct timespec tv;
gettimeoffset = pxa_gettimeoffset; gettimeoffset = pxa_gettimeoffset;
set_rtc = pxa_set_rtc; set_rtc = pxa_set_rtc;
xtime.tv_sec = pxa_get_rtc_time();
tv.tv_nsec = 0;
tv.tv_sec = pxa_get_rtc_time();
do_settimeofday(&tv);
timer_irq.handler = pxa_timer_interrupt; timer_irq.handler = pxa_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */ OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */ OSSR = 0xf; /* clear status on all timers */
......
...@@ -92,9 +92,15 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -92,9 +92,15 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
void __init time_init(void) void __init time_init(void)
{ {
struct timespec tv;
gettimeoffset = sa1100_gettimeoffset; gettimeoffset = sa1100_gettimeoffset;
set_rtc = sa1100_set_rtc; set_rtc = sa1100_set_rtc;
xtime.tv_sec = sa1100_get_rtc_time();
tv.tv.nsec = 0;
tv.tv_sec = sa1100_get_rtc_time();
do_settimeofday(&tv);
timer_irq.handler = sa1100_timer_interrupt; timer_irq.handler = sa1100_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */ OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */ OSSR = 0xf; /* clear status on all timers */
......
...@@ -34,8 +34,6 @@ void __init time_init(void) ...@@ -34,8 +34,6 @@ void __init time_init(void)
outb(HZ_TIME & 0xff, 0x40); /* LSB of count */ outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
outb(HZ_TIME >> 8, 0x40); outb(HZ_TIME >> 8, 0x40);
xtime.tv_sec = 0;
timer_irq.handler = timer_interrupt; timer_irq.handler = timer_interrupt;
setup_irq(IRQ_TIMER, &timer_irq); setup_irq(IRQ_TIMER, &timer_irq);
} }
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