Ignore:
File:
1 edited

Legend:

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

    ra582dff rf9b2cb4c  
    4040#include <as.h>
    4141#include <sysinfo.h>
    42 #include <libarch/ddi.h>
    4342#include <libarch/barrier.h>
    4443#include <stdio.h>
     
    7776        int clients_connected;
    7877        /** time at which the system booted */
    79         time_t boottime;
     78        struct timeval boot_time;
    8079} rtc_t;
    8180
     
    9897static int rtc_dev_remove(ddf_dev_t *dev);
    9998static void rtc_register_write(rtc_t *rtc, int reg, int data);
    100 static time_t uptime_get(void);
    10199static bool is_battery_ok(rtc_t *rtc);
    102100static int  rtc_fun_online(ddf_fun_t *fun);
     
    206204        ddf_msg(LVL_DEBUG, "rtc_dev_initialize %s", ddf_dev_get_name(rtc->dev));
    207205
    208         rtc->boottime = 0;
     206        rtc->boot_time.tv_sec = 0;
     207        rtc->boot_time.tv_usec = 0;
    209208        rtc->clients_connected = 0;
    210209
     
    214213        /* Connect to the parent's driver */
    215214
    216         parent_sess = ddf_dev_parent_sess_create(rtc->dev, EXCHANGE_SERIALIZE);
     215        parent_sess = ddf_dev_parent_sess_create(rtc->dev);
    217216        if (!parent_sess) {
    218217                ddf_msg(LVL_ERROR, "Failed to connect to parent driver\
     
    327326        fibril_mutex_lock(&rtc->mutex);
    328327
    329         if (rtc->boottime != 0) {
     328        if (rtc->boot_time.tv_sec) {
    330329                /* There is no need to read the current time from the
    331330                 * device because it has already been cached.
    332331                 */
    333332
    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);
    336337                fibril_mutex_unlock(&rtc->mutex);
    337338
    338                 return time_local2tm(cur_time, t);
     339                return time_tv2tm(&curtime, t);
    339340        }
    340341
     
    345346        }
    346347
     348        /* Microseconds are below RTC's resolution, assume 0. */
     349        t->tm_usec = 0;
     350
    347351        /* now read the registers */
    348352        do {
    349353                /* 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);
    354359                t->tm_hour = rtc_register_read(rtc, RTC_HOUR);
    355360                t->tm_mday = rtc_register_read(rtc, RTC_DAY);
    356                 t->tm_mon  = rtc_register_read(rtc, RTC_MON);
     361                t->tm_mon = rtc_register_read(rtc, RTC_MON);
    357362                t->tm_year = rtc_register_read(rtc, RTC_YEAR);
    358363
    359364                /* Now check if it is stable */
    360         } while(t->tm_sec  != rtc_register_read(rtc, RTC_SEC) ||
    361             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) ||
    362367            t->tm_mday != rtc_register_read(rtc, RTC_DAY) ||
    363             t->tm_mon  != rtc_register_read(rtc, RTC_MON) ||
     368            t->tm_mon != rtc_register_read(rtc, RTC_MON) ||
    364369            t->tm_year != rtc_register_read(rtc, RTC_YEAR));
    365370
     
    367372        bool _12h_mode = !(rtc_register_read(rtc, RTC_STATUS_B) &
    368373            RTC_B_24H);
    369 
    370374        if (_12h_mode) {
    371375                /* The RTC is working in 12h mode, check if it is AM or PM */
     
    379383        /* Check if the RTC is working in BCD mode */
    380384        bcd_mode = !(rtc_register_read(rtc, RTC_STATUS_B) & RTC_B_BCD);
    381 
    382385        if (bcd_mode) {
    383                 t->tm_sec  = bcd2bin(t->tm_sec);
    384                 t->tm_min  = bcd2bin(t->tm_min);
     386                t->tm_sec = bcd2bin(t->tm_sec);
     387                t->tm_min = bcd2bin(t->tm_min);
    385388                t->tm_hour = bcd2bin(t->tm_hour);
    386389                t->tm_mday = bcd2bin(t->tm_mday);
    387                 t->tm_mon  = bcd2bin(t->tm_mon);
     390                t->tm_mon = bcd2bin(t->tm_mon);
    388391                t->tm_year = bcd2bin(t->tm_year);
    389392        }
     
    415418                result = EINVAL;
    416419        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);
    418426                result = EOK;
    419427        }
     
    436444        bool bcd_mode;
    437445        time_t norm_time;
    438         time_t uptime;
     446        struct timeval uptime;
     447        struct timeval ntv;
    439448        int  reg_b;
    440449        int  reg_a;
     
    446455                return EINVAL;
    447456
    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)) {
    450462                /* This is not acceptable */
    451463                return EINVAL;
     
    459471        }
    460472
    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;
    463476
    464477        /* Detect the RTC epoch */
     
    732745}
    733746
    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 
    744747static int
    745748rtc_fun_online(ddf_fun_t *fun)
Note: See TracChangeset for help on using the changeset viewer.