Changes in uspace/drv/time/cmos-rtc/cmos-rtc.c [a582dff:f9b2cb4c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/time/cmos-rtc/cmos-rtc.c
ra582dff rf9b2cb4c 40 40 #include <as.h> 41 41 #include <sysinfo.h> 42 #include <libarch/ddi.h>43 42 #include <libarch/barrier.h> 44 43 #include <stdio.h> … … 77 76 int clients_connected; 78 77 /** time at which the system booted */ 79 time_t boottime;78 struct timeval boot_time; 80 79 } rtc_t; 81 80 … … 98 97 static int rtc_dev_remove(ddf_dev_t *dev); 99 98 static void rtc_register_write(rtc_t *rtc, int reg, int data); 100 static time_t uptime_get(void);101 99 static bool is_battery_ok(rtc_t *rtc); 102 100 static int rtc_fun_online(ddf_fun_t *fun); … … 206 204 ddf_msg(LVL_DEBUG, "rtc_dev_initialize %s", ddf_dev_get_name(rtc->dev)); 207 205 208 rtc->boottime = 0; 206 rtc->boot_time.tv_sec = 0; 207 rtc->boot_time.tv_usec = 0; 209 208 rtc->clients_connected = 0; 210 209 … … 214 213 /* Connect to the parent's driver */ 215 214 216 parent_sess = ddf_dev_parent_sess_create(rtc->dev , EXCHANGE_SERIALIZE);215 parent_sess = ddf_dev_parent_sess_create(rtc->dev); 217 216 if (!parent_sess) { 218 217 ddf_msg(LVL_ERROR, "Failed to connect to parent driver\ … … 327 326 fibril_mutex_lock(&rtc->mutex); 328 327 329 if (rtc->boot time != 0) {328 if (rtc->boot_time.tv_sec) { 330 329 /* There is no need to read the current time from the 331 330 * device because it has already been cached. 332 331 */ 333 332 334 time_t cur_time = rtc->boottime + uptime_get(); 335 333 struct timeval curtime; 334 335 getuptime(&curtime); 336 tv_add(&curtime, &rtc->boot_time); 336 337 fibril_mutex_unlock(&rtc->mutex); 337 338 338 return time_ local2tm(cur_time, t);339 return time_tv2tm(&curtime, t); 339 340 } 340 341 … … 345 346 } 346 347 348 /* Microseconds are below RTC's resolution, assume 0. */ 349 t->tm_usec = 0; 350 347 351 /* now read the registers */ 348 352 do { 349 353 /* Suspend until the update process has finished */ 350 while (rtc_update_in_progress(rtc)); 351 352 t->tm_sec = rtc_register_read(rtc, RTC_SEC); 353 t->tm_min = rtc_register_read(rtc, RTC_MIN); 354 while (rtc_update_in_progress(rtc)) 355 ; 356 357 t->tm_sec = rtc_register_read(rtc, RTC_SEC); 358 t->tm_min = rtc_register_read(rtc, RTC_MIN); 354 359 t->tm_hour = rtc_register_read(rtc, RTC_HOUR); 355 360 t->tm_mday = rtc_register_read(rtc, RTC_DAY); 356 t->tm_mon 361 t->tm_mon = rtc_register_read(rtc, RTC_MON); 357 362 t->tm_year = rtc_register_read(rtc, RTC_YEAR); 358 363 359 364 /* Now check if it is stable */ 360 } while(t->tm_sec 361 t->tm_min 365 } while(t->tm_sec != rtc_register_read(rtc, RTC_SEC) || 366 t->tm_min != rtc_register_read(rtc, RTC_MIN) || 362 367 t->tm_mday != rtc_register_read(rtc, RTC_DAY) || 363 t->tm_mon 368 t->tm_mon != rtc_register_read(rtc, RTC_MON) || 364 369 t->tm_year != rtc_register_read(rtc, RTC_YEAR)); 365 370 … … 367 372 bool _12h_mode = !(rtc_register_read(rtc, RTC_STATUS_B) & 368 373 RTC_B_24H); 369 370 374 if (_12h_mode) { 371 375 /* The RTC is working in 12h mode, check if it is AM or PM */ … … 379 383 /* Check if the RTC is working in BCD mode */ 380 384 bcd_mode = !(rtc_register_read(rtc, RTC_STATUS_B) & RTC_B_BCD); 381 382 385 if (bcd_mode) { 383 t->tm_sec 384 t->tm_min 386 t->tm_sec = bcd2bin(t->tm_sec); 387 t->tm_min = bcd2bin(t->tm_min); 385 388 t->tm_hour = bcd2bin(t->tm_hour); 386 389 t->tm_mday = bcd2bin(t->tm_mday); 387 t->tm_mon 390 t->tm_mon = bcd2bin(t->tm_mon); 388 391 t->tm_year = bcd2bin(t->tm_year); 389 392 } … … 415 418 result = EINVAL; 416 419 else { 417 rtc->boottime = r - uptime_get(); 420 struct timeval uptime; 421 422 getuptime(&uptime); 423 rtc->boot_time.tv_sec = r; 424 rtc->boot_time.tv_usec = t->tm_usec; /* normalized */ 425 tv_sub(&rtc->boot_time, &uptime); 418 426 result = EOK; 419 427 } … … 436 444 bool bcd_mode; 437 445 time_t norm_time; 438 time_t uptime; 446 struct timeval uptime; 447 struct timeval ntv; 439 448 int reg_b; 440 449 int reg_a; … … 446 455 return EINVAL; 447 456 448 uptime = uptime_get(); 449 if (norm_time <= uptime) { 457 ntv.tv_sec = norm_time; 458 ntv.tv_usec = t->tm_usec; 459 getuptime(&uptime); 460 461 if (tv_gteq(&uptime, &ntv)) { 450 462 /* This is not acceptable */ 451 463 return EINVAL; … … 459 471 } 460 472 461 /* boottime must be recomputed */ 462 rtc->boottime = 0; 473 /* boot_time must be recomputed */ 474 rtc->boot_time.tv_sec = 0; 475 rtc->boot_time.tv_usec = 0; 463 476 464 477 /* Detect the RTC epoch */ … … 732 745 } 733 746 734 static time_t735 uptime_get(void)736 {737 struct timeval tv;738 739 getuptime(&tv);740 741 return tv.tv_sec;742 }743 744 747 static int 745 748 rtc_fun_online(ddf_fun_t *fun)
Note:
See TracChangeset
for help on using the changeset viewer.