time.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:19k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: time.c,v 1.41.2.1 2002/01/23 14:35:45 davem Exp $
  2.  * time.c: UltraSparc timer and TOD clock support.
  3.  *
  4.  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  5.  * Copyright (C) 1998 Eddie C. Dost   (ecd@skynet.be)
  6.  *
  7.  * Based largely on code which is:
  8.  *
  9.  * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/errno.h>
  13. #include <linux/sched.h>
  14. #include <linux/kernel.h>
  15. #include <linux/param.h>
  16. #include <linux/string.h>
  17. #include <linux/mm.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/timex.h>
  20. #include <linux/init.h>
  21. #include <linux/ioport.h>
  22. #include <linux/mc146818rtc.h>
  23. #include <linux/delay.h>
  24. #include <asm/oplib.h>
  25. #include <asm/mostek.h>
  26. #include <asm/timer.h>
  27. #include <asm/irq.h>
  28. #include <asm/io.h>
  29. #include <asm/sbus.h>
  30. #include <asm/fhc.h>
  31. #include <asm/pbm.h>
  32. #include <asm/ebus.h>
  33. #include <asm/isa.h>
  34. #include <asm/starfire.h>
  35. extern rwlock_t xtime_lock;
  36. spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
  37. spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
  38. unsigned long mstk48t02_regs = 0UL;
  39. #ifdef CONFIG_PCI
  40. unsigned long ds1287_regs = 0UL;
  41. #endif
  42. static unsigned long mstk48t08_regs = 0UL;
  43. static unsigned long mstk48t59_regs = 0UL;
  44. static int set_rtc_mmss(unsigned long);
  45. /* timer_interrupt() needs to keep up the real-time clock,
  46.  * as well as call the "do_timer()" routine every clocktick
  47.  *
  48.  * NOTE: On SUN5 systems the ticker interrupt comes in using 2
  49.  *       interrupts, one at level14 and one with softint bit 0.
  50.  */
  51. unsigned long timer_tick_offset;
  52. unsigned long timer_tick_compare;
  53. unsigned long timer_ticks_per_usec_quotient;
  54. static __inline__ void timer_check_rtc(void)
  55. {
  56. /* last time the cmos clock got updated */
  57. static long last_rtc_update=0;
  58. /* Determine when to update the Mostek clock. */
  59. if ((time_status & STA_UNSYNC) == 0 &&
  60.     xtime.tv_sec > last_rtc_update + 660 &&
  61.     xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
  62.     xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
  63. if (set_rtc_mmss(xtime.tv_sec) == 0)
  64. last_rtc_update = xtime.tv_sec;
  65. else
  66. last_rtc_update = xtime.tv_sec - 600;
  67. /* do it again in 60 s */
  68. }
  69. }
  70. void sparc64_do_profile(unsigned long pc, unsigned long o7)
  71. {
  72. if (prof_buffer && current->pid) {
  73. extern int _stext;
  74. extern int rwlock_impl_begin, rwlock_impl_end;
  75. extern int atomic_impl_begin, atomic_impl_end;
  76. extern int __memcpy_begin, __memcpy_end;
  77. extern int __bzero_begin, __bzero_end;
  78. extern int __bitops_begin, __bitops_end;
  79. if ((pc >= (unsigned long) &atomic_impl_begin &&
  80.      pc < (unsigned long) &atomic_impl_end) ||
  81.     (pc >= (unsigned long) &rwlock_impl_begin &&
  82.      pc < (unsigned long) &rwlock_impl_end) ||
  83.     (pc >= (unsigned long) &__memcpy_begin &&
  84.      pc < (unsigned long) &__memcpy_end) ||
  85.     (pc >= (unsigned long) &__bzero_begin &&
  86.      pc < (unsigned long) &__bzero_end) ||
  87.     (pc >= (unsigned long) &__bitops_begin &&
  88.      pc < (unsigned long) &__bitops_end))
  89. pc = o7;
  90. pc -= (unsigned long) &_stext;
  91. pc >>= prof_shift;
  92. if(pc >= prof_len)
  93. pc = prof_len - 1;
  94. atomic_inc((atomic_t *)&prof_buffer[pc]);
  95. }
  96. }
  97. static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  98. {
  99. unsigned long ticks, pstate;
  100. write_lock(&xtime_lock);
  101. do {
  102. #ifndef CONFIG_SMP
  103. if ((regs->tstate & TSTATE_PRIV) != 0)
  104. sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]);
  105. #endif
  106. do_timer(regs);
  107. /* Guarentee that the following sequences execute
  108.  * uninterrupted.
  109.  */
  110. __asm__ __volatile__("rdpr %%pstate, %0nt"
  111.      "wrpr %0, %1, %%pstate"
  112.      : "=r" (pstate)
  113.      : "i" (PSTATE_IE));
  114. /* Workaround for Spitfire Errata (#54 I think??), I discovered
  115.  * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
  116.  * number 103640.
  117.  *
  118.  * On Blackbird writes to %tick_cmpr can fail, the
  119.  * workaround seems to be to execute the wr instruction
  120.  * at the start of an I-cache line, and perform a dummy
  121.  * read back from %tick_cmpr right after writing to it. -DaveM
  122.  *
  123.  * Just to be anal we add a workaround for Spitfire
  124.  * Errata 50 by preventing pipeline bypasses on the
  125.  * final read of the %tick register into a compare
  126.  * instruction.  The Errata 50 description states
  127.  * that %tick is not prone to this bug, but I am not
  128.  * taking any chances.
  129.  */
  130. if (!SPARC64_USE_STICK) {
  131. __asm__ __volatile__(
  132. " rd %%tick_cmpr, %0n"
  133. " ba,pt %%xcc, 1fn"
  134. "  add %0, %2, %0n"
  135. " .align 64n"
  136. "1:  wr %0, 0, %%tick_cmprn"
  137. " rd %%tick_cmpr, %%g0n"
  138. " rd %%tick, %1n"
  139. " mov %1, %1"
  140. : "=&r" (timer_tick_compare), "=r" (ticks)
  141. : "r" (timer_tick_offset));
  142. } else {
  143. __asm__ __volatile__(
  144. " rd %%asr25, %0n"
  145. " add %0, %2, %0n"
  146. " wr %0, 0, %%asr25n"
  147. " rd %%asr24, %1"
  148. : "=&r" (timer_tick_compare), "=r" (ticks)
  149. : "r" (timer_tick_offset));
  150. }
  151. /* Restore PSTATE_IE. */
  152. __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
  153.      : /* no outputs */
  154.      : "r" (pstate));
  155. } while (ticks >= timer_tick_compare);
  156. timer_check_rtc();
  157. write_unlock(&xtime_lock);
  158. }
  159. #ifdef CONFIG_SMP
  160. void timer_tick_interrupt(struct pt_regs *regs)
  161. {
  162. write_lock(&xtime_lock);
  163. do_timer(regs);
  164. /*
  165.  * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
  166.  */
  167. if (!SPARC64_USE_STICK) {
  168. __asm__ __volatile__(
  169. " rd %%tick_cmpr, %0n"
  170. " add %0, %1, %0"
  171. : "=&r" (timer_tick_compare)
  172. : "r" (timer_tick_offset));
  173. } else {
  174. __asm__ __volatile__(
  175. " rd %%asr25, %0n"
  176. " add %0, %1, %0"
  177. : "=&r" (timer_tick_compare)
  178. : "r" (timer_tick_offset));
  179. }
  180. timer_check_rtc();
  181. write_unlock(&xtime_lock);
  182. }
  183. #endif
  184. /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
  185. static void __init kick_start_clock(void)
  186. {
  187. unsigned long regs = mstk48t02_regs;
  188. u8 sec, tmp;
  189. int i, count;
  190. prom_printf("CLOCK: Clock was stopped. Kick start ");
  191. spin_lock_irq(&mostek_lock);
  192. /* Turn on the kick start bit to start the oscillator. */
  193. tmp = mostek_read(regs + MOSTEK_CREG);
  194. tmp |= MSTK_CREG_WRITE;
  195. mostek_write(regs + MOSTEK_CREG, tmp);
  196. tmp = mostek_read(regs + MOSTEK_SEC);
  197. tmp &= ~MSTK_STOP;
  198. mostek_write(regs + MOSTEK_SEC, tmp);
  199. tmp = mostek_read(regs + MOSTEK_HOUR);
  200. tmp |= MSTK_KICK_START;
  201. mostek_write(regs + MOSTEK_HOUR, tmp);
  202. tmp = mostek_read(regs + MOSTEK_CREG);
  203. tmp &= ~MSTK_CREG_WRITE;
  204. mostek_write(regs + MOSTEK_CREG, tmp);
  205. spin_unlock_irq(&mostek_lock);
  206. /* Delay to allow the clock oscillator to start. */
  207. sec = MSTK_REG_SEC(regs);
  208. for (i = 0; i < 3; i++) {
  209. while (sec == MSTK_REG_SEC(regs))
  210. for (count = 0; count < 100000; count++)
  211. /* nothing */ ;
  212. prom_printf(".");
  213. sec = MSTK_REG_SEC(regs);
  214. }
  215. prom_printf("n");
  216. spin_lock_irq(&mostek_lock);
  217. /* Turn off kick start and set a "valid" time and date. */
  218. tmp = mostek_read(regs + MOSTEK_CREG);
  219. tmp |= MSTK_CREG_WRITE;
  220. mostek_write(regs + MOSTEK_CREG, tmp);
  221. tmp = mostek_read(regs + MOSTEK_HOUR);
  222. tmp &= ~MSTK_KICK_START;
  223. mostek_write(regs + MOSTEK_HOUR, tmp);
  224. MSTK_SET_REG_SEC(regs,0);
  225. MSTK_SET_REG_MIN(regs,0);
  226. MSTK_SET_REG_HOUR(regs,0);
  227. MSTK_SET_REG_DOW(regs,5);
  228. MSTK_SET_REG_DOM(regs,1);
  229. MSTK_SET_REG_MONTH(regs,8);
  230. MSTK_SET_REG_YEAR(regs,1996 - MSTK_YEAR_ZERO);
  231. tmp = mostek_read(regs + MOSTEK_CREG);
  232. tmp &= ~MSTK_CREG_WRITE;
  233. mostek_write(regs + MOSTEK_CREG, tmp);
  234. spin_unlock_irq(&mostek_lock);
  235. /* Ensure the kick start bit is off. If it isn't, turn it off. */
  236. while (mostek_read(regs + MOSTEK_HOUR) & MSTK_KICK_START) {
  237. prom_printf("CLOCK: Kick start still on!n");
  238. spin_lock_irq(&mostek_lock);
  239. tmp = mostek_read(regs + MOSTEK_CREG);
  240. tmp |= MSTK_CREG_WRITE;
  241. mostek_write(regs + MOSTEK_CREG, tmp);
  242. tmp = mostek_read(regs + MOSTEK_HOUR);
  243. tmp &= ~MSTK_KICK_START;
  244. mostek_write(regs + MOSTEK_HOUR, tmp);
  245. tmp = mostek_read(regs + MOSTEK_CREG);
  246. tmp &= ~MSTK_CREG_WRITE;
  247. mostek_write(regs + MOSTEK_CREG, tmp);
  248. spin_unlock_irq(&mostek_lock);
  249. }
  250. prom_printf("CLOCK: Kick start procedure successful.n");
  251. }
  252. /* Return nonzero if the clock chip battery is low. */
  253. static int __init has_low_battery(void)
  254. {
  255. unsigned long regs = mstk48t02_regs;
  256. u8 data1, data2;
  257. spin_lock_irq(&mostek_lock);
  258. data1 = mostek_read(regs + MOSTEK_EEPROM); /* Read some data. */
  259. mostek_write(regs + MOSTEK_EEPROM, ~data1); /* Write back the complement. */
  260. data2 = mostek_read(regs + MOSTEK_EEPROM); /* Read back the complement. */
  261. mostek_write(regs + MOSTEK_EEPROM, data1); /* Restore original value. */
  262. spin_unlock_irq(&mostek_lock);
  263. return (data1 == data2); /* Was the write blocked? */
  264. }
  265. #ifndef BCD_TO_BIN
  266. #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
  267. #endif
  268. #ifndef BIN_TO_BCD
  269. #define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
  270. #endif
  271. /* Probe for the real time clock chip. */
  272. static void __init set_system_time(void)
  273. {
  274. unsigned int year, mon, day, hour, min, sec;
  275. unsigned long mregs = mstk48t02_regs;
  276. #ifdef CONFIG_PCI
  277. unsigned long dregs = ds1287_regs;
  278. #else
  279. unsigned long dregs = 0UL;
  280. #endif
  281. u8 tmp;
  282. if (!mregs && !dregs) {
  283. prom_printf("Something wrong, clock regs not mapped yet.n");
  284. prom_halt();
  285. }
  286. if (mregs) {
  287. spin_lock_irq(&mostek_lock);
  288. /* Traditional Mostek chip. */
  289. tmp = mostek_read(mregs + MOSTEK_CREG);
  290. tmp |= MSTK_CREG_READ;
  291. mostek_write(mregs + MOSTEK_CREG, tmp);
  292. sec = MSTK_REG_SEC(mregs);
  293. min = MSTK_REG_MIN(mregs);
  294. hour = MSTK_REG_HOUR(mregs);
  295. day = MSTK_REG_DOM(mregs);
  296. mon = MSTK_REG_MONTH(mregs);
  297. year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
  298. } else {
  299. int i;
  300. /* Dallas 12887 RTC chip. */
  301. /* Stolen from arch/i386/kernel/time.c, see there for
  302.  * credits and descriptive comments.
  303.  */
  304. for (i = 0; i < 1000000; i++) {
  305. if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
  306. break;
  307. udelay(10);
  308. }
  309. for (i = 0; i < 1000000; i++) {
  310. if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
  311. break;
  312. udelay(10);
  313. }
  314. do {
  315. sec  = CMOS_READ(RTC_SECONDS);
  316. min  = CMOS_READ(RTC_MINUTES);
  317. hour = CMOS_READ(RTC_HOURS);
  318. day  = CMOS_READ(RTC_DAY_OF_MONTH);
  319. mon  = CMOS_READ(RTC_MONTH);
  320. year = CMOS_READ(RTC_YEAR);
  321. } while (sec != CMOS_READ(RTC_SECONDS));
  322. if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
  323. BCD_TO_BIN(sec);
  324. BCD_TO_BIN(min);
  325. BCD_TO_BIN(hour);
  326. BCD_TO_BIN(day);
  327. BCD_TO_BIN(mon);
  328. BCD_TO_BIN(year);
  329. }
  330. if ((year += 1900) < 1970)
  331. year += 100;
  332. }
  333. xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
  334. xtime.tv_usec = 0;
  335. if (mregs) {
  336. tmp = mostek_read(mregs + MOSTEK_CREG);
  337. tmp &= ~MSTK_CREG_READ;
  338. mostek_write(mregs + MOSTEK_CREG, tmp);
  339. spin_unlock_irq(&mostek_lock);
  340. }
  341. }
  342. void __init clock_probe(void)
  343. {
  344. struct linux_prom_registers clk_reg[2];
  345. char model[128];
  346. int node, busnd = -1, err;
  347. unsigned long flags;
  348. #ifdef CONFIG_PCI
  349. struct linux_ebus *ebus = NULL;
  350. struct isa_bridge *isa_br = NULL;
  351. #endif
  352. static int invoked = 0;
  353. if (invoked)
  354. return;
  355. invoked = 1;
  356. if (this_is_starfire) {
  357. /* davem suggests we keep this within the 4M locked kernel image */
  358. static char obp_gettod[256];
  359. static u32 unix_tod;
  360. sprintf(obp_gettod, "h# %08x unix-gettod",
  361. (unsigned int) (long) &unix_tod);
  362. prom_feval(obp_gettod);
  363. xtime.tv_sec = unix_tod;
  364. xtime.tv_usec = 0;
  365. return;
  366. }
  367. __save_and_cli(flags);
  368. if(central_bus != NULL) {
  369. busnd = central_bus->child->prom_node;
  370. }
  371. #ifdef CONFIG_PCI
  372. else if (ebus_chain != NULL) {
  373. ebus = ebus_chain;
  374. busnd = ebus->prom_node;
  375. } else if (isa_chain != NULL) {
  376. isa_br = isa_chain;
  377. busnd = isa_br->prom_node;
  378. }
  379. #endif
  380. else if (sbus_root != NULL) {
  381. busnd = sbus_root->prom_node;
  382. }
  383. if (busnd == -1) {
  384. prom_printf("clock_probe: problem, cannot find bus to search.n");
  385. prom_halt();
  386. }
  387. node = prom_getchild(busnd);
  388. while (1) {
  389. if (!node)
  390. model[0] = 0;
  391. else
  392. prom_getstring(node, "model", model, sizeof(model));
  393. if (strcmp(model, "mk48t02") &&
  394.     strcmp(model, "mk48t08") &&
  395.     strcmp(model, "mk48t59") &&
  396.     strcmp(model, "m5819") &&
  397.     strcmp(model, "ds1287")) {
  398.     if (node)
  399. node = prom_getsibling(node);
  400. #ifdef CONFIG_PCI
  401. while ((node == 0) && ebus != NULL) {
  402. ebus = ebus->next;
  403. if (ebus != NULL) {
  404. busnd = ebus->prom_node;
  405. node = prom_getchild(busnd);
  406. }
  407. }
  408. while ((node == 0) && isa_br != NULL) {
  409. isa_br = isa_br->next;
  410. if (isa_br != NULL) {
  411. busnd = isa_br->prom_node;
  412. node = prom_getchild(busnd);
  413. }
  414. }
  415. #endif
  416. if (node == 0) {
  417. prom_printf("clock_probe: Cannot find timer chipn");
  418. prom_halt();
  419. }
  420. continue;
  421. }
  422. err = prom_getproperty(node, "reg", (char *)clk_reg,
  423.        sizeof(clk_reg));
  424. if(err == -1) {
  425. prom_printf("clock_probe: Cannot get Mostek reg propertyn");
  426. prom_halt();
  427. }
  428. if(central_bus) {
  429. apply_fhc_ranges(central_bus->child, clk_reg, 1);
  430. apply_central_ranges(central_bus, clk_reg, 1);
  431. }
  432. #ifdef CONFIG_PCI
  433. else if (ebus_chain != NULL) {
  434. struct linux_ebus_device *edev;
  435. for_each_ebusdev(edev, ebus)
  436. if (edev->prom_node == node)
  437. break;
  438. if (edev == NULL) {
  439. if (isa_chain != NULL)
  440. goto try_isa_clock;
  441. prom_printf("%s: Mostek not probed by EBUSn",
  442.     __FUNCTION__);
  443. prom_halt();
  444. }
  445. if (!strcmp(model, "ds1287") ||
  446.     !strcmp(model, "m5819")) {
  447. ds1287_regs = edev->resource[0].start;
  448. } else {
  449. mstk48t59_regs = edev->resource[0].start;
  450. mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
  451. }
  452. break;
  453. } else if (isa_chain != NULL) {
  454. struct isa_device *isadev;
  455. try_isa_clock:
  456. for_each_isadev(isadev, isa_br)
  457. if (isadev->prom_node == node)
  458. break;
  459. if (isadev == NULL) {
  460. prom_printf("%s: Mostek not probed by ISAn");
  461. prom_halt();
  462. }
  463. if (!strcmp(model, "ds1287") ||
  464.     !strcmp(model, "m5819")) {
  465. ds1287_regs = isadev->resource.start;
  466. } else {
  467. mstk48t59_regs = isadev->resource.start;
  468. mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
  469. }
  470. break;
  471. }
  472. #endif
  473. else {
  474. if (sbus_root->num_sbus_ranges) {
  475. int nranges = sbus_root->num_sbus_ranges;
  476. int rngc;
  477. for (rngc = 0; rngc < nranges; rngc++)
  478. if (clk_reg[0].which_io ==
  479.     sbus_root->sbus_ranges[rngc].ot_child_space)
  480. break;
  481. if (rngc == nranges) {
  482. prom_printf("clock_probe: Cannot find ranges for "
  483.     "clock regs.n");
  484. prom_halt();
  485. }
  486. clk_reg[0].which_io =
  487. sbus_root->sbus_ranges[rngc].ot_parent_space;
  488. clk_reg[0].phys_addr +=
  489. sbus_root->sbus_ranges[rngc].ot_parent_base;
  490. }
  491. }
  492. if(model[5] == '0' && model[6] == '2') {
  493. mstk48t02_regs = (((u64)clk_reg[0].phys_addr) |
  494.   (((u64)clk_reg[0].which_io)<<32UL));
  495. } else if(model[5] == '0' && model[6] == '8') {
  496. mstk48t08_regs = (((u64)clk_reg[0].phys_addr) |
  497.   (((u64)clk_reg[0].which_io)<<32UL));
  498. mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
  499. } else {
  500. mstk48t59_regs = (((u64)clk_reg[0].phys_addr) |
  501.   (((u64)clk_reg[0].which_io)<<32UL));
  502. mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
  503. }
  504. break;
  505. }
  506. if (mstk48t02_regs != 0UL) {
  507. /* Report a low battery voltage condition. */
  508. if (has_low_battery())
  509. prom_printf("NVRAM: Low battery voltage!n");
  510. /* Kick start the clock if it is completely stopped. */
  511. if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
  512. kick_start_clock();
  513. }
  514. set_system_time();
  515. __restore_flags(flags);
  516. }
  517. extern void init_timers(void (*func)(int, void *, struct pt_regs *),
  518. unsigned long *);
  519. void __init time_init(void)
  520. {
  521. /* clock_probe() is now done at end of [se]bus_init on sparc64
  522.  * so that sbus, fhc and ebus bus information is probed and
  523.  * available.
  524.  */
  525. unsigned long clock;
  526. init_timers(timer_interrupt, &clock);
  527. timer_ticks_per_usec_quotient = ((1UL<<32) / (clock / 1000020));
  528. }
  529. static __inline__ unsigned long do_gettimeoffset(void)
  530. {
  531. unsigned long ticks;
  532. if (!SPARC64_USE_STICK) {
  533. __asm__ __volatile__(
  534. " rd %%tick, %%g1n"
  535. " add %1, %%g1, %0n"
  536. " sub %0, %2, %0n"
  537. : "=r" (ticks)
  538. : "r" (timer_tick_offset), "r" (timer_tick_compare)
  539. : "g1", "g2");
  540. } else {
  541. __asm__ __volatile__("rd %%asr24, %%g1nt"
  542.      "add %1, %%g1, %0nt"
  543.      "sub %0, %2, %0nt"
  544.      : "=&r" (ticks)
  545.      : "r" (timer_tick_offset), "r" (timer_tick_compare)
  546.      : "g1");
  547. }
  548. return (ticks * timer_ticks_per_usec_quotient) >> 32UL;
  549. }
  550. void do_settimeofday(struct timeval *tv)
  551. {
  552. if (this_is_starfire)
  553. return;
  554. write_lock_irq(&xtime_lock);
  555. tv->tv_usec -= do_gettimeoffset();
  556. if(tv->tv_usec < 0) {
  557. tv->tv_usec += 1000000;
  558. tv->tv_sec--;
  559. }
  560. xtime = *tv;
  561. time_adjust = 0; /* stop active adjtime() */
  562. time_status |= STA_UNSYNC;
  563. time_maxerror = NTP_PHASE_LIMIT;
  564. time_esterror = NTP_PHASE_LIMIT;
  565. write_unlock_irq(&xtime_lock);
  566. }
  567. static int set_rtc_mmss(unsigned long nowtime)
  568. {
  569. int real_seconds, real_minutes, chip_minutes;
  570. unsigned long mregs = mstk48t02_regs;
  571. #ifdef CONFIG_PCI
  572. unsigned long dregs = ds1287_regs;
  573. #else
  574. unsigned long dregs = 0UL;
  575. #endif
  576. unsigned long flags;
  577. u8 tmp;
  578. /* 
  579.  * Not having a register set can lead to trouble.
  580.  * Also starfire doesnt have a tod clock.
  581.  */
  582. if (!mregs && !dregs) 
  583. return -1;
  584. if (mregs) {
  585. spin_lock_irqsave(&mostek_lock, flags);
  586. /* Read the current RTC minutes. */
  587. tmp = mostek_read(mregs + MOSTEK_CREG);
  588. tmp |= MSTK_CREG_READ;
  589. mostek_write(mregs + MOSTEK_CREG, tmp);
  590. chip_minutes = MSTK_REG_MIN(mregs);
  591. tmp = mostek_read(mregs + MOSTEK_CREG);
  592. tmp &= ~MSTK_CREG_READ;
  593. mostek_write(mregs + MOSTEK_CREG, tmp);
  594. /*
  595.  * since we're only adjusting minutes and seconds,
  596.  * don't interfere with hour overflow. This avoids
  597.  * messing with unknown time zones but requires your
  598.  * RTC not to be off by more than 15 minutes
  599.  */
  600. real_seconds = nowtime % 60;
  601. real_minutes = nowtime / 60;
  602. if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
  603. real_minutes += 30; /* correct for half hour time zone */
  604. real_minutes %= 60;
  605. if (abs(real_minutes - chip_minutes) < 30) {
  606. tmp = mostek_read(mregs + MOSTEK_CREG);
  607. tmp |= MSTK_CREG_WRITE;
  608. mostek_write(mregs + MOSTEK_CREG, tmp);
  609. MSTK_SET_REG_SEC(mregs,real_seconds);
  610. MSTK_SET_REG_MIN(mregs,real_minutes);
  611. tmp = mostek_read(mregs + MOSTEK_CREG);
  612. tmp &= ~MSTK_CREG_WRITE;
  613. mostek_write(mregs + MOSTEK_CREG, tmp);
  614. spin_unlock_irqrestore(&mostek_lock, flags);
  615. return 0;
  616. } else {
  617. spin_unlock_irqrestore(&mostek_lock, flags);
  618. return -1;
  619. }
  620. } else {
  621. int retval = 0;
  622. unsigned char save_control, save_freq_select;
  623. /* Stolen from arch/i386/kernel/time.c, see there for
  624.  * credits and descriptive comments.
  625.  */
  626. spin_lock_irqsave(&rtc_lock, flags);
  627. save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
  628. CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
  629. save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
  630. CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
  631. chip_minutes = CMOS_READ(RTC_MINUTES);
  632. if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
  633. BCD_TO_BIN(chip_minutes);
  634. real_seconds = nowtime % 60;
  635. real_minutes = nowtime / 60;
  636. if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
  637. real_minutes += 30;
  638. real_minutes %= 60;
  639. if (abs(real_minutes - chip_minutes) < 30) {
  640. if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
  641. BIN_TO_BCD(real_seconds);
  642. BIN_TO_BCD(real_minutes);
  643. }
  644. CMOS_WRITE(real_seconds,RTC_SECONDS);
  645. CMOS_WRITE(real_minutes,RTC_MINUTES);
  646. } else {
  647. printk(KERN_WARNING
  648.        "set_rtc_mmss: can't update from %d to %dn",
  649.        chip_minutes, real_minutes);
  650. retval = -1;
  651. }
  652. CMOS_WRITE(save_control, RTC_CONTROL);
  653. CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
  654. spin_unlock_irqrestore(&rtc_lock, flags);
  655. return retval;
  656. }
  657. }