aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/time.c2
-rw-r--r--arch/x86/kernel/hpet.c2
-rw-r--r--arch/x86/kernel/tsc.c2
-rw-r--r--drivers/clocksource/sh_cmt.c35
-rw-r--r--include/linux/clocksource.h5
-rw-r--r--include/linux/timex.h3
-rw-r--r--kernel/posix-timers.c2
-rw-r--r--kernel/time/clocksource.c14
-rw-r--r--kernel/time/ntp.c10
-rw-r--r--kernel/time/timekeeping.c1
10 files changed, 34 insertions, 42 deletions
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index a35c661e5e89..47a192781b0a 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -61,7 +61,7 @@ unsigned long long sched_clock(void)
61 61
62#ifdef CONFIG_PARAVIRT 62#ifdef CONFIG_PARAVIRT
63static void 63static void
64paravirt_clocksource_resume(void) 64paravirt_clocksource_resume(struct clocksource *cs)
65{ 65{
66 if (pv_time_ops.clocksource_resume) 66 if (pv_time_ops.clocksource_resume)
67 pv_time_ops.clocksource_resume(); 67 pv_time_ops.clocksource_resume();
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ad80a1c718c6..ee4fa1bfcb33 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -266,7 +266,7 @@ static void hpet_resume_device(void)
266 force_hpet_resume(); 266 force_hpet_resume();
267} 267}
268 268
269static void hpet_resume_counter(void) 269static void hpet_resume_counter(struct clocksource *cs)
270{ 270{
271 hpet_resume_device(); 271 hpet_resume_device();
272 hpet_restart_counter(); 272 hpet_restart_counter();
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 23066ecf12fa..208a857c679f 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -740,7 +740,7 @@ static cycle_t __vsyscall_fn vread_tsc(void)
740} 740}
741#endif 741#endif
742 742
743static void resume_tsc(void) 743static void resume_tsc(struct clocksource *cs)
744{ 744{
745 clocksource_tsc.cycle_last = 0; 745 clocksource_tsc.cycle_last = 0;
746} 746}
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 6fe4f7701188..578595c4425d 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -40,7 +40,6 @@ struct sh_cmt_priv {
40 struct platform_device *pdev; 40 struct platform_device *pdev;
41 41
42 unsigned long flags; 42 unsigned long flags;
43 unsigned long flags_suspend;
44 unsigned long match_value; 43 unsigned long match_value;
45 unsigned long next_match_value; 44 unsigned long next_match_value;
46 unsigned long max_match_value; 45 unsigned long max_match_value;
@@ -432,6 +431,11 @@ static void sh_cmt_clocksource_disable(struct clocksource *cs)
432 sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); 431 sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
433} 432}
434 433
434static void sh_cmt_clocksource_resume(struct clocksource *cs)
435{
436 sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
437}
438
435static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, 439static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
436 char *name, unsigned long rating) 440 char *name, unsigned long rating)
437{ 441{
@@ -442,6 +446,8 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
442 cs->read = sh_cmt_clocksource_read; 446 cs->read = sh_cmt_clocksource_read;
443 cs->enable = sh_cmt_clocksource_enable; 447 cs->enable = sh_cmt_clocksource_enable;
444 cs->disable = sh_cmt_clocksource_disable; 448 cs->disable = sh_cmt_clocksource_disable;
449 cs->suspend = sh_cmt_clocksource_disable;
450 cs->resume = sh_cmt_clocksource_resume;
445 cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); 451 cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
446 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 452 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
447 pr_info("sh_cmt: %s used as clock source\n", cs->name); 453 pr_info("sh_cmt: %s used as clock source\n", cs->name);
@@ -674,38 +680,11 @@ static int __devexit sh_cmt_remove(struct platform_device *pdev)
674 return -EBUSY; /* cannot unregister clockevent and clocksource */ 680 return -EBUSY; /* cannot unregister clockevent and clocksource */
675} 681}
676 682
677static int sh_cmt_suspend(struct device *dev)
678{
679 struct platform_device *pdev = to_platform_device(dev);
680 struct sh_cmt_priv *p = platform_get_drvdata(pdev);
681
682 /* save flag state and stop CMT channel */
683 p->flags_suspend = p->flags;
684 sh_cmt_stop(p, p->flags);
685 return 0;
686}
687
688static int sh_cmt_resume(struct device *dev)
689{
690 struct platform_device *pdev = to_platform_device(dev);
691 struct sh_cmt_priv *p = platform_get_drvdata(pdev);
692
693 /* start CMT channel from saved state */
694 sh_cmt_start(p, p->flags_suspend);
695 return 0;
696}
697
698static struct dev_pm_ops sh_cmt_dev_pm_ops = {
699 .suspend = sh_cmt_suspend,
700 .resume = sh_cmt_resume,
701};
702
703static struct platform_driver sh_cmt_device_driver = { 683static struct platform_driver sh_cmt_device_driver = {
704 .probe = sh_cmt_probe, 684 .probe = sh_cmt_probe,
705 .remove = __devexit_p(sh_cmt_remove), 685 .remove = __devexit_p(sh_cmt_remove),
706 .driver = { 686 .driver = {
707 .name = "sh_cmt", 687 .name = "sh_cmt",
708 .pm = &sh_cmt_dev_pm_ops,
709 } 688 }
710}; 689};
711 690
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 8a4a130cc196..4bca8b60cdf7 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -154,6 +154,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
154 * @max_idle_ns: max idle time permitted by the clocksource (nsecs) 154 * @max_idle_ns: max idle time permitted by the clocksource (nsecs)
155 * @flags: flags describing special properties 155 * @flags: flags describing special properties
156 * @vread: vsyscall based read 156 * @vread: vsyscall based read
157 * @suspend: suspend function for the clocksource, if necessary
157 * @resume: resume function for the clocksource, if necessary 158 * @resume: resume function for the clocksource, if necessary
158 */ 159 */
159struct clocksource { 160struct clocksource {
@@ -172,7 +173,8 @@ struct clocksource {
172 u64 max_idle_ns; 173 u64 max_idle_ns;
173 unsigned long flags; 174 unsigned long flags;
174 cycle_t (*vread)(void); 175 cycle_t (*vread)(void);
175 void (*resume)(void); 176 void (*suspend)(struct clocksource *cs);
177 void (*resume)(struct clocksource *cs);
176#ifdef CONFIG_IA64 178#ifdef CONFIG_IA64
177 void *fsys_mmio; /* used by fsyscall asm code */ 179 void *fsys_mmio; /* used by fsyscall asm code */
178#define CLKSRC_FSYS_MMIO_SET(mmio, addr) ((mmio) = (addr)) 180#define CLKSRC_FSYS_MMIO_SET(mmio, addr) ((mmio) = (addr))
@@ -277,6 +279,7 @@ extern void clocksource_unregister(struct clocksource*);
277extern void clocksource_touch_watchdog(void); 279extern void clocksource_touch_watchdog(void);
278extern struct clocksource* clocksource_get_next(void); 280extern struct clocksource* clocksource_get_next(void);
279extern void clocksource_change_rating(struct clocksource *cs, int rating); 281extern void clocksource_change_rating(struct clocksource *cs, int rating);
282extern void clocksource_suspend(void);
280extern void clocksource_resume(void); 283extern void clocksource_resume(void);
281extern struct clocksource * __init __weak clocksource_default_clock(void); 284extern struct clocksource * __init __weak clocksource_default_clock(void);
282extern void clocksource_mark_unstable(struct clocksource *cs); 285extern void clocksource_mark_unstable(struct clocksource *cs);
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 94f8faecdcbc..7a082b32d8e1 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -238,9 +238,6 @@ extern int tickadj; /* amount of adjustment per tick */
238 * phase-lock loop variables 238 * phase-lock loop variables
239 */ 239 */
240extern int time_status; /* clock synchronization status bits */ 240extern int time_status; /* clock synchronization status bits */
241extern long time_maxerror; /* maximum error */
242extern long time_esterror; /* estimated error */
243
244extern long time_adjust; /* The amount of adjtime left */ 241extern long time_adjust; /* The amount of adjtime left */
245 242
246extern void ntp_init(void); 243extern void ntp_init(void);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 495440779ce3..00d1fda58ab6 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -256,7 +256,7 @@ static int posix_get_monotonic_coarse(clockid_t which_clock,
256 return 0; 256 return 0;
257} 257}
258 258
259int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp) 259static int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
260{ 260{
261 *tp = ktime_to_timespec(KTIME_LOW_RES); 261 *tp = ktime_to_timespec(KTIME_LOW_RES);
262 return 0; 262 return 0;
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 13700833c181..1f663d23e85e 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -453,6 +453,18 @@ static inline int clocksource_watchdog_kthread(void *data) { return 0; }
453#endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ 453#endif /* CONFIG_CLOCKSOURCE_WATCHDOG */
454 454
455/** 455/**
456 * clocksource_suspend - suspend the clocksource(s)
457 */
458void clocksource_suspend(void)
459{
460 struct clocksource *cs;
461
462 list_for_each_entry_reverse(cs, &clocksource_list, list)
463 if (cs->suspend)
464 cs->suspend(cs);
465}
466
467/**
456 * clocksource_resume - resume the clocksource(s) 468 * clocksource_resume - resume the clocksource(s)
457 */ 469 */
458void clocksource_resume(void) 470void clocksource_resume(void)
@@ -461,7 +473,7 @@ void clocksource_resume(void)
461 473
462 list_for_each_entry(cs, &clocksource_list, list) 474 list_for_each_entry(cs, &clocksource_list, list)
463 if (cs->resume) 475 if (cs->resume)
464 cs->resume(); 476 cs->resume(cs);
465 477
466 clocksource_resume_watchdog(); 478 clocksource_resume_watchdog();
467} 479}
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 4800f933910e..7c0f180d6e9d 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -58,10 +58,10 @@ static s64 time_offset;
58static long time_constant = 2; 58static long time_constant = 2;
59 59
60/* maximum error (usecs): */ 60/* maximum error (usecs): */
61long time_maxerror = NTP_PHASE_LIMIT; 61static long time_maxerror = NTP_PHASE_LIMIT;
62 62
63/* estimated error (usecs): */ 63/* estimated error (usecs): */
64long time_esterror = NTP_PHASE_LIMIT; 64static long time_esterror = NTP_PHASE_LIMIT;
65 65
66/* frequency offset (scaled nsecs/secs): */ 66/* frequency offset (scaled nsecs/secs): */
67static s64 time_freq; 67static s64 time_freq;
@@ -142,11 +142,11 @@ static void ntp_update_offset(long offset)
142 * Select how the frequency is to be controlled 142 * Select how the frequency is to be controlled
143 * and in which mode (PLL or FLL). 143 * and in which mode (PLL or FLL).
144 */ 144 */
145 secs = xtime.tv_sec - time_reftime; 145 secs = get_seconds() - time_reftime;
146 if (unlikely(time_status & STA_FREQHOLD)) 146 if (unlikely(time_status & STA_FREQHOLD))
147 secs = 0; 147 secs = 0;
148 148
149 time_reftime = xtime.tv_sec; 149 time_reftime = get_seconds();
150 150
151 offset64 = offset; 151 offset64 = offset;
152 freq_adj = (offset64 * secs) << 152 freq_adj = (offset64 * secs) <<
@@ -368,7 +368,7 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts)
368 * reference time to current time. 368 * reference time to current time.
369 */ 369 */
370 if (!(time_status & STA_PLL) && (txc->status & STA_PLL)) 370 if (!(time_status & STA_PLL) && (txc->status & STA_PLL))
371 time_reftime = xtime.tv_sec; 371 time_reftime = get_seconds();
372 372
373 /* only set allowed bits */ 373 /* only set allowed bits */
374 time_status &= STA_RONLY; 374 time_status &= STA_RONLY;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e2ab064c6d41..16736379a9ca 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -622,6 +622,7 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
622 write_sequnlock_irqrestore(&xtime_lock, flags); 622 write_sequnlock_irqrestore(&xtime_lock, flags);
623 623
624 clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); 624 clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
625 clocksource_suspend();
625 626
626 return 0; 627 return 0;
627} 628}