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