blob: 6b8f4d22abc69a2b2d49118281cb7f04cdb63e85 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/time.c
7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003, 2004 Paul Mundt
10 * Copyright (C) 2003 Richard Curnow
11 *
12 * Original TMU/RTC code taken from sh version.
13 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
14 * Some code taken from i386 version.
15 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
16 */
17
18#include <linux/config.h>
19#include <linux/errno.h>
20#include <linux/rwsem.h>
21#include <linux/sched.h>
22#include <linux/kernel.h>
23#include <linux/param.h>
24#include <linux/string.h>
25#include <linux/mm.h>
26#include <linux/interrupt.h>
27#include <linux/time.h>
28#include <linux/delay.h>
29#include <linux/init.h>
30#include <linux/profile.h>
31#include <linux/smp.h>
Alexey Dobriyan4940fb42006-02-01 03:06:09 -080032#include <linux/module.h>
Matt Mackall4f3a36a2006-03-28 01:56:10 -080033#include <linux/bcd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
35#include <asm/registers.h> /* required by inline __asm__ stmt. */
36
37#include <asm/processor.h>
38#include <asm/uaccess.h>
39#include <asm/io.h>
40#include <asm/irq.h>
41#include <asm/delay.h>
42
43#include <linux/timex.h>
44#include <linux/irq.h>
45#include <asm/hardware.h>
46
47#define TMU_TOCR_INIT 0x00
48#define TMU0_TCR_INIT 0x0020
49#define TMU_TSTR_INIT 1
50#define TMU_TSTR_OFF 0
51
52/* RCR1 Bits */
53#define RCR1_CF 0x80 /* Carry Flag */
54#define RCR1_CIE 0x10 /* Carry Interrupt Enable */
55#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */
56#define RCR1_AF 0x01 /* Alarm Flag */
57
58/* RCR2 Bits */
59#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */
60#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */
61#define RCR2_RTCEN 0x08 /* ENable RTC */
62#define RCR2_ADJ 0x04 /* ADJustment (30-second) */
63#define RCR2_RESET 0x02 /* Reset bit */
64#define RCR2_START 0x01 /* Start bit */
65
66/* Clock, Power and Reset Controller */
67#define CPRC_BLOCK_OFF 0x01010000
68#define CPRC_BASE PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF
69
70#define FRQCR (cprc_base+0x0)
71#define WTCSR (cprc_base+0x0018)
72#define STBCR (cprc_base+0x0030)
73
74/* Time Management Unit */
75#define TMU_BLOCK_OFF 0x01020000
76#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
77#define TMU0_BASE tmu_base + 0x8 + (0xc * 0x0)
78#define TMU1_BASE tmu_base + 0x8 + (0xc * 0x1)
79#define TMU2_BASE tmu_base + 0x8 + (0xc * 0x2)
80
81#define TMU_TOCR tmu_base+0x0 /* Byte access */
82#define TMU_TSTR tmu_base+0x4 /* Byte access */
83
84#define TMU0_TCOR TMU0_BASE+0x0 /* Long access */
85#define TMU0_TCNT TMU0_BASE+0x4 /* Long access */
86#define TMU0_TCR TMU0_BASE+0x8 /* Word access */
87
88/* Real Time Clock */
89#define RTC_BLOCK_OFF 0x01040000
90#define RTC_BASE PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF
91
92#define R64CNT rtc_base+0x00
93#define RSECCNT rtc_base+0x04
94#define RMINCNT rtc_base+0x08
95#define RHRCNT rtc_base+0x0c
96#define RWKCNT rtc_base+0x10
97#define RDAYCNT rtc_base+0x14
98#define RMONCNT rtc_base+0x18
99#define RYRCNT rtc_base+0x1c /* 16bit */
100#define RSECAR rtc_base+0x20
101#define RMINAR rtc_base+0x24
102#define RHRAR rtc_base+0x28
103#define RWKAR rtc_base+0x2c
104#define RDAYAR rtc_base+0x30
105#define RMONAR rtc_base+0x34
106#define RCR1 rtc_base+0x38
107#define RCR2 rtc_base+0x3c
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109#define TICK_SIZE (tick_nsec / 1000)
110
111extern unsigned long wall_jiffies;
112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113static unsigned long tmu_base, rtc_base;
114unsigned long cprc_base;
115
116/* Variables to allow interpolation of time of day to resolution better than a
117 * jiffy. */
118
119/* This is effectively protected by xtime_lock */
120static unsigned long ctc_last_interrupt;
121static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */
122
123#define CTC_JIFFY_SCALE_SHIFT 40
124
125/* 2**CTC_JIFFY_SCALE_SHIFT / ctc_ticks_per_jiffy */
126static unsigned long long scaled_recip_ctc_ticks_per_jiffy;
127
128/* Estimate number of microseconds that have elapsed since the last timer tick,
129 by scaling the delta that has occured in the CTC register.
130
131 WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at
132 the CPU clock rate. If the CPU sleeps, the CTC stops counting. Bear this
133 in mind if enabling SLEEP_WORKS in process.c. In that case, this algorithm
134 probably needs to use TMU.TCNT0 instead. This will work even if the CPU is
135 sleeping, though will be coarser.
136
137 FIXME : What if usecs_per_tick is moving around too much, e.g. if an adjtime
138 is running or if the freq or tick arguments of adjtimex are modified after
139 we have calibrated the scaling factor? This will result in either a jump at
140 the end of a tick period, or a wrap backwards at the start of the next one,
141 if the application is reading the time of day often enough. I think we
142 ought to do better than this. For this reason, usecs_per_jiffy is left
143 separated out in the calculation below. This allows some future hook into
144 the adjtime-related stuff in kernel/timer.c to remove this hazard.
145
146*/
147
148static unsigned long usecs_since_tick(void)
149{
150 unsigned long long current_ctc;
151 long ctc_ticks_since_interrupt;
152 unsigned long long ull_ctc_ticks_since_interrupt;
153 unsigned long result;
154
155 unsigned long long mul1_out;
156 unsigned long long mul1_out_high;
157 unsigned long long mul2_out_low, mul2_out_high;
158
159 /* Read CTC register */
160 asm ("getcon cr62, %0" : "=r" (current_ctc));
161 /* Note, the CTC counts down on each CPU clock, not up.
162 Note(2), use long type to get correct wraparound arithmetic when
163 the counter crosses zero. */
164 ctc_ticks_since_interrupt = (long) ctc_last_interrupt - (long) current_ctc;
165 ull_ctc_ticks_since_interrupt = (unsigned long long) ctc_ticks_since_interrupt;
166
167 /* Inline assembly to do 32x32x32->64 multiplier */
168 asm volatile ("mulu.l %1, %2, %0" :
169 "=r" (mul1_out) :
170 "r" (ull_ctc_ticks_since_interrupt), "r" (usecs_per_jiffy));
171
172 mul1_out_high = mul1_out >> 32;
173
174 asm volatile ("mulu.l %1, %2, %0" :
175 "=r" (mul2_out_low) :
176 "r" (mul1_out), "r" (scaled_recip_ctc_ticks_per_jiffy));
177
178#if 1
179 asm volatile ("mulu.l %1, %2, %0" :
180 "=r" (mul2_out_high) :
181 "r" (mul1_out_high), "r" (scaled_recip_ctc_ticks_per_jiffy));
182#endif
183
184 result = (unsigned long) (((mul2_out_high << 32) + mul2_out_low) >> CTC_JIFFY_SCALE_SHIFT);
185
186 return result;
187}
188
189void do_gettimeofday(struct timeval *tv)
190{
191 unsigned long flags;
192 unsigned long seq;
193 unsigned long usec, sec;
194
195 do {
196 seq = read_seqbegin_irqsave(&xtime_lock, flags);
197 usec = usecs_since_tick();
198 {
199 unsigned long lost = jiffies - wall_jiffies;
200
201 if (lost)
202 usec += lost * (1000000 / HZ);
203 }
204
205 sec = xtime.tv_sec;
206 usec += xtime.tv_nsec / 1000;
207 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
208
209 while (usec >= 1000000) {
210 usec -= 1000000;
211 sec++;
212 }
213
214 tv->tv_sec = sec;
215 tv->tv_usec = usec;
216}
217
218int do_settimeofday(struct timespec *tv)
219{
220 time_t wtm_sec, sec = tv->tv_sec;
221 long wtm_nsec, nsec = tv->tv_nsec;
222
223 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
224 return -EINVAL;
225
226 write_seqlock_irq(&xtime_lock);
227 /*
228 * This is revolting. We need to set "xtime" correctly. However, the
229 * value in this location is the value at the most recent update of
230 * wall time. Discover what correction gettimeofday() would have
231 * made, and then undo it!
232 */
233 nsec -= 1000 * (usecs_since_tick() +
234 (jiffies - wall_jiffies) * (1000000 / HZ));
235
236 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
237 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
238
239 set_normalized_timespec(&xtime, sec, nsec);
240 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
241
john stultzb149ee22005-09-06 15:17:46 -0700242 ntp_clear();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 write_sequnlock_irq(&xtime_lock);
244 clock_was_set();
245
246 return 0;
247}
Al Viro943eae02005-10-29 07:32:07 +0100248EXPORT_SYMBOL(do_settimeofday);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
250static int set_rtc_time(unsigned long nowtime)
251{
252 int retval = 0;
253 int real_seconds, real_minutes, cmos_minutes;
254
255 ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */
256
257 cmos_minutes = ctrl_inb(RMINCNT);
258 BCD_TO_BIN(cmos_minutes);
259
260 /*
261 * since we're only adjusting minutes and seconds,
262 * don't interfere with hour overflow. This avoids
263 * messing with unknown time zones but requires your
264 * RTC not to be off by more than 15 minutes
265 */
266 real_seconds = nowtime % 60;
267 real_minutes = nowtime / 60;
268 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
269 real_minutes += 30; /* correct for half hour time zone */
270 real_minutes %= 60;
271
272 if (abs(real_minutes - cmos_minutes) < 30) {
273 BIN_TO_BCD(real_seconds);
274 BIN_TO_BCD(real_minutes);
275 ctrl_outb(real_seconds, RSECCNT);
276 ctrl_outb(real_minutes, RMINCNT);
277 } else {
278 printk(KERN_WARNING
279 "set_rtc_time: can't update from %d to %d\n",
280 cmos_minutes, real_minutes);
281 retval = -1;
282 }
283
284 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */
285
286 return retval;
287}
288
289/* last time the RTC clock got updated */
290static long last_rtc_update = 0;
291
292/*
293 * timer_interrupt() needs to keep up the real-time clock,
294 * as well as call the "do_timer()" routine every clocktick
295 */
Adrian Bunk7f4bde92005-09-06 15:17:39 -0700296static inline void do_timer_interrupt(int irq, struct pt_regs *regs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297{
298 unsigned long long current_ctc;
299 asm ("getcon cr62, %0" : "=r" (current_ctc));
300 ctc_last_interrupt = (unsigned long) current_ctc;
301
302 do_timer(regs);
303#ifndef CONFIG_SMP
304 update_process_times(user_mode(regs));
305#endif
306 profile_tick(CPU_PROFILING, regs);
307
308#ifdef CONFIG_HEARTBEAT
309 {
310 extern void heartbeat(void);
311
312 heartbeat();
313 }
314#endif
315
316 /*
317 * If we have an externally synchronized Linux clock, then update
318 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
319 * called as close as possible to 500 ms before the new second starts.
320 */
john stultzb149ee22005-09-06 15:17:46 -0700321 if (ntp_synced() &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 xtime.tv_sec > last_rtc_update + 660 &&
323 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
324 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
325 if (set_rtc_time(xtime.tv_sec) == 0)
326 last_rtc_update = xtime.tv_sec;
327 else
328 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
329 }
330}
331
332/*
333 * This is the same as the above, except we _also_ save the current
334 * Time Stamp Counter value at the time of the timer interrupt, so that
335 * we later on can estimate the time of day more exactly.
336 */
337static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
338{
339 unsigned long timer_status;
340
341 /* Clear UNF bit */
342 timer_status = ctrl_inw(TMU0_TCR);
343 timer_status &= ~0x100;
344 ctrl_outw(timer_status, TMU0_TCR);
345
346 /*
347 * Here we are in the timer irq handler. We just have irqs locally
348 * disabled but we don't know if the timer_bh is running on the other
349 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
350 * the irq version of write_lock because as just said we have irq
351 * locally disabled. -arca
352 */
353 write_lock(&xtime_lock);
Adrian Bunk7f4bde92005-09-06 15:17:39 -0700354 do_timer_interrupt(irq, regs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 write_unlock(&xtime_lock);
356
357 return IRQ_HANDLED;
358}
359
360static unsigned long get_rtc_time(void)
361{
362 unsigned int sec, min, hr, wk, day, mon, yr, yr100;
363
364 again:
365 do {
366 ctrl_outb(0, RCR1); /* Clear CF-bit */
367 sec = ctrl_inb(RSECCNT);
368 min = ctrl_inb(RMINCNT);
369 hr = ctrl_inb(RHRCNT);
370 wk = ctrl_inb(RWKCNT);
371 day = ctrl_inb(RDAYCNT);
372 mon = ctrl_inb(RMONCNT);
373 yr = ctrl_inw(RYRCNT);
374 yr100 = (yr >> 8);
375 yr &= 0xff;
376 } while ((ctrl_inb(RCR1) & RCR1_CF) != 0);
377
378 BCD_TO_BIN(yr100);
379 BCD_TO_BIN(yr);
380 BCD_TO_BIN(mon);
381 BCD_TO_BIN(day);
382 BCD_TO_BIN(hr);
383 BCD_TO_BIN(min);
384 BCD_TO_BIN(sec);
385
386 if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
387 hr > 23 || min > 59 || sec > 59) {
388 printk(KERN_ERR
389 "SH RTC: invalid value, resetting to 1 Jan 2000\n");
390 ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */
391 ctrl_outb(0, RSECCNT);
392 ctrl_outb(0, RMINCNT);
393 ctrl_outb(0, RHRCNT);
394 ctrl_outb(6, RWKCNT);
395 ctrl_outb(1, RDAYCNT);
396 ctrl_outb(1, RMONCNT);
397 ctrl_outw(0x2000, RYRCNT);
398 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */
399 goto again;
400 }
401
402 return mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
403}
404
405static __init unsigned int get_cpu_hz(void)
406{
407 unsigned int count;
408 unsigned long __dummy;
409 unsigned long ctc_val_init, ctc_val;
410
411 /*
412 ** Regardless the toolchain, force the compiler to use the
413 ** arbitrary register r3 as a clock tick counter.
Adrian Bunk2a10e0b2006-01-08 01:02:15 -0800414 ** NOTE: r3 must be in accordance with sh64_rtc_interrupt()
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 */
416 register unsigned long long __rtc_irq_flag __asm__ ("r3");
417
418 local_irq_enable();
419 do {} while (ctrl_inb(R64CNT) != 0);
420 ctrl_outb(RCR1_CIE, RCR1); /* Enable carry interrupt */
421
422 /*
423 * r3 is arbitrary. CDC does not support "=z".
424 */
425 ctc_val_init = 0xffffffff;
426 ctc_val = ctc_val_init;
427
428 asm volatile("gettr tr0, %1\n\t"
429 "putcon %0, " __CTC "\n\t"
430 "and %2, r63, %2\n\t"
431 "pta $+4, tr0\n\t"
432 "beq/l %2, r63, tr0\n\t"
433 "ptabs %1, tr0\n\t"
434 "getcon " __CTC ", %0\n\t"
435 : "=r"(ctc_val), "=r" (__dummy), "=r" (__rtc_irq_flag)
436 : "0" (0));
437 local_irq_disable();
438 /*
439 * SH-3:
440 * CPU clock = 4 stages * loop
441 * tst rm,rm if id ex
442 * bt/s 1b if id ex
443 * add #1,rd if id ex
444 * (if) pipe line stole
445 * tst rm,rm if id ex
446 * ....
447 *
448 *
449 * SH-4:
450 * CPU clock = 6 stages * loop
451 * I don't know why.
452 * ....
453 *
454 * SH-5:
455 * Use CTC register to count. This approach returns the right value
456 * even if the I-cache is disabled (e.g. whilst debugging.)
457 *
458 */
459
460 count = ctc_val_init - ctc_val; /* CTC counts down */
461
462#if defined (CONFIG_SH_SIMULATOR)
463 /*
464 * Let's pretend we are a 5MHz SH-5 to avoid a too
465 * little timer interval. Also to keep delay
466 * calibration within a reasonable time.
467 */
468 return 5000000;
469#else
470 /*
471 * This really is count by the number of clock cycles
472 * by the ratio between a complete R64CNT
473 * wrap-around (128) and CUI interrupt being raised (64).
474 */
475 return count*2;
476#endif
477}
478
Adrian Bunk2a10e0b2006-01-08 01:02:15 -0800479static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id,
480 struct pt_regs *regs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481{
482 ctrl_outb(0, RCR1); /* Disable Carry Interrupts */
483 regs->regs[3] = 1; /* Using r3 */
484
485 return IRQ_HANDLED;
486}
487
488static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL};
Adrian Bunk2a10e0b2006-01-08 01:02:15 -0800489static struct irqaction irq1 = { sh64_rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
491void __init time_init(void)
492{
493 unsigned int cpu_clock, master_clock, bus_clock, module_clock;
494 unsigned long interval;
495 unsigned long frqcr, ifc, pfc;
496 static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
497#define bfc_table ifc_table /* Same */
498#define pfc_table ifc_table /* Same */
499
500 tmu_base = onchip_remap(TMU_BASE, 1024, "TMU");
501 if (!tmu_base) {
502 panic("Unable to remap TMU\n");
503 }
504
505 rtc_base = onchip_remap(RTC_BASE, 1024, "RTC");
506 if (!rtc_base) {
507 panic("Unable to remap RTC\n");
508 }
509
510 cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC");
511 if (!cprc_base) {
512 panic("Unable to remap CPRC\n");
513 }
514
515 xtime.tv_sec = get_rtc_time();
516 xtime.tv_nsec = 0;
517
518 setup_irq(TIMER_IRQ, &irq0);
519 setup_irq(RTC_IRQ, &irq1);
520
521 /* Check how fast it is.. */
522 cpu_clock = get_cpu_hz();
523
524 /* Note careful order of operations to maintain reasonable precision and avoid overflow. */
525 scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ));
526
527 disable_irq(RTC_IRQ);
528
529 printk("CPU clock: %d.%02dMHz\n",
530 (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
531 {
532 unsigned short bfc;
533 frqcr = ctrl_inl(FRQCR);
534 ifc = ifc_table[(frqcr>> 6) & 0x0007];
535 bfc = bfc_table[(frqcr>> 3) & 0x0007];
536 pfc = pfc_table[(frqcr>> 12) & 0x0007];
537 master_clock = cpu_clock * ifc;
538 bus_clock = master_clock/bfc;
539 }
540
541 printk("Bus clock: %d.%02dMHz\n",
542 (bus_clock/1000000), (bus_clock % 1000000)/10000);
543 module_clock = master_clock/pfc;
544 printk("Module clock: %d.%02dMHz\n",
545 (module_clock/1000000), (module_clock % 1000000)/10000);
546 interval = (module_clock/(HZ*4));
547
548 printk("Interval = %ld\n", interval);
549
550 current_cpu_data.cpu_clock = cpu_clock;
551 current_cpu_data.master_clock = master_clock;
552 current_cpu_data.bus_clock = bus_clock;
553 current_cpu_data.module_clock = module_clock;
554
555 /* Start TMU0 */
556 ctrl_outb(TMU_TSTR_OFF, TMU_TSTR);
557 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
558 ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
559 ctrl_outl(interval, TMU0_TCOR);
560 ctrl_outl(interval, TMU0_TCNT);
561 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
562}
563
564void enter_deep_standby(void)
565{
566 /* Disable watchdog timer */
567 ctrl_outl(0xa5000000, WTCSR);
568 /* Configure deep standby on sleep */
569 ctrl_outl(0x03, STBCR);
570
571#ifdef CONFIG_SH_ALPHANUMERIC
572 {
573 extern void mach_alphanum(int position, unsigned char value);
574 extern void mach_alphanum_brightness(int setting);
575 char halted[] = "Halted. ";
576 int i;
577 mach_alphanum_brightness(6); /* dimmest setting above off */
578 for (i=0; i<8; i++) {
579 mach_alphanum(i, halted[i]);
580 }
581 asm __volatile__ ("synco");
582 }
583#endif
584
585 asm __volatile__ ("sleep");
586 asm __volatile__ ("synci");
587 asm __volatile__ ("nop");
588 asm __volatile__ ("nop");
589 asm __volatile__ ("nop");
590 asm __volatile__ ("nop");
591 panic("Unexpected wakeup!\n");
592}
593
594/*
595 * Scheduler clock - returns current time in nanosec units.
596 */
597unsigned long long sched_clock(void)
598{
599 return (unsigned long long)jiffies * (1000000000 / HZ);
600}
601