Changeset 7f9d97f3 in mainline for uspace/drv/time/cmos-rtc/cmos-rtc.c


Ignore:
Timestamp:
2015-03-14T21:48:01Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
270bf4f
Parents:
c0c38c7c
Message:

Make gettimeofday() return the actual microseconds.

Enhance struct tm to also have a field to hold microseconds and make
sure that this information propagates from the RTC driver.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/time/cmos-rtc/cmos-rtc.c

    rc0c38c7c r7f9d97f3  
    7676        int clients_connected;
    7777        /** time at which the system booted */
    78         time_t boottime;
     78        struct timeval boot_time;
    7979} rtc_t;
    8080
     
    9797static int rtc_dev_remove(ddf_dev_t *dev);
    9898static void rtc_register_write(rtc_t *rtc, int reg, int data);
    99 static time_t uptime_get(void);
    10099static bool is_battery_ok(rtc_t *rtc);
    101100static int  rtc_fun_online(ddf_fun_t *fun);
     
    205204        ddf_msg(LVL_DEBUG, "rtc_dev_initialize %s", ddf_dev_get_name(rtc->dev));
    206205
    207         rtc->boottime = 0;
     206        rtc->boot_time.tv_sec = 0;
     207        rtc->boot_time.tv_usec = 0;
    208208        rtc->clients_connected = 0;
    209209
     
    326326        fibril_mutex_lock(&rtc->mutex);
    327327
    328         if (rtc->boottime != 0) {
     328        if (rtc->boot_time.tv_sec) {
    329329                /* There is no need to read the current time from the
    330330                 * device because it has already been cached.
    331331                 */
    332332
    333                 time_t cur_time = rtc->boottime + uptime_get();
    334 
     333                struct timeval curtime;
     334               
     335                getuptime(&curtime);
     336                tv_add(&curtime, &rtc->boot_time);
    335337                fibril_mutex_unlock(&rtc->mutex);
    336338
    337                 return time_local2tm(cur_time, t);
     339                return time_tv2tm(&curtime, t);
    338340        }
    339341
     
    344346        }
    345347
     348        /* Microseconds are below RTC's resolution, assume 0. */
     349        t->tm_usec = 0;
     350
    346351        /* now read the registers */
    347352        do {
    348353                /* Suspend until the update process has finished */
    349                 while (rtc_update_in_progress(rtc));
    350 
    351                 t->tm_sec  = rtc_register_read(rtc, RTC_SEC);
    352                 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);
    353359                t->tm_hour = rtc_register_read(rtc, RTC_HOUR);
    354360                t->tm_mday = rtc_register_read(rtc, RTC_DAY);
    355                 t->tm_mon  = rtc_register_read(rtc, RTC_MON);
     361                t->tm_mon = rtc_register_read(rtc, RTC_MON);
    356362                t->tm_year = rtc_register_read(rtc, RTC_YEAR);
    357363
    358364                /* Now check if it is stable */
    359         } while(t->tm_sec  != rtc_register_read(rtc, RTC_SEC) ||
    360             t->tm_min  != rtc_register_read(rtc, RTC_MIN) ||
     365        } while(t->tm_sec != rtc_register_read(rtc, RTC_SEC) ||
     366            t->tm_min != rtc_register_read(rtc, RTC_MIN) ||
    361367            t->tm_mday != rtc_register_read(rtc, RTC_DAY) ||
    362             t->tm_mon  != rtc_register_read(rtc, RTC_MON) ||
     368            t->tm_mon != rtc_register_read(rtc, RTC_MON) ||
    363369            t->tm_year != rtc_register_read(rtc, RTC_YEAR));
    364370
     
    366372        bool _12h_mode = !(rtc_register_read(rtc, RTC_STATUS_B) &
    367373            RTC_B_24H);
    368 
    369374        if (_12h_mode) {
    370375                /* The RTC is working in 12h mode, check if it is AM or PM */
     
    378383        /* Check if the RTC is working in BCD mode */
    379384        bcd_mode = !(rtc_register_read(rtc, RTC_STATUS_B) & RTC_B_BCD);
    380 
    381385        if (bcd_mode) {
    382                 t->tm_sec  = bcd2bin(t->tm_sec);
    383                 t->tm_min  = bcd2bin(t->tm_min);
     386                t->tm_sec = bcd2bin(t->tm_sec);
     387                t->tm_min = bcd2bin(t->tm_min);
    384388                t->tm_hour = bcd2bin(t->tm_hour);
    385389                t->tm_mday = bcd2bin(t->tm_mday);
    386                 t->tm_mon  = bcd2bin(t->tm_mon);
     390                t->tm_mon = bcd2bin(t->tm_mon);
    387391                t->tm_year = bcd2bin(t->tm_year);
    388392        }
     
    414418                result = EINVAL;
    415419        else {
    416                 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);
    417426                result = EOK;
    418427        }
     
    435444        bool bcd_mode;
    436445        time_t norm_time;
    437         time_t uptime;
     446        struct timeval uptime;
     447        struct timeval ntv;
    438448        int  reg_b;
    439449        int  reg_a;
     
    445455                return EINVAL;
    446456
    447         uptime = uptime_get();
    448         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)) {
    449462                /* This is not acceptable */
    450463                return EINVAL;
     
    458471        }
    459472
    460         /* boottime must be recomputed */
    461         rtc->boottime = 0;
     473        /* boot_time must be recomputed */
     474        rtc->boot_time.tv_sec = 0;
     475        rtc->boot_time.tv_usec = 0;
    462476
    463477        /* Detect the RTC epoch */
     
    731745}
    732746
    733 static time_t
    734 uptime_get(void)
    735 {
    736         struct timeval tv;
    737 
    738         getuptime(&tv);
    739 
    740         return tv.tv_sec;
    741 }
    742 
    743747static int
    744748rtc_fun_online(ddf_fun_t *fun)
Note: See TracChangeset for help on using the changeset viewer.