Ignore:
File:
1 edited

Legend:

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

    rf9b2cb4c ra582dff  
    4040#include <as.h>
    4141#include <sysinfo.h>
     42#include <libarch/ddi.h>
    4243#include <libarch/barrier.h>
    4344#include <stdio.h>
     
    7677        int clients_connected;
    7778        /** time at which the system booted */
    78         struct timeval boot_time;
     79        time_t boottime;
    7980} rtc_t;
    8081
     
    9798static int rtc_dev_remove(ddf_dev_t *dev);
    9899static void rtc_register_write(rtc_t *rtc, int reg, int data);
     100static time_t uptime_get(void);
    99101static bool is_battery_ok(rtc_t *rtc);
    100102static int  rtc_fun_online(ddf_fun_t *fun);
     
    204206        ddf_msg(LVL_DEBUG, "rtc_dev_initialize %s", ddf_dev_get_name(rtc->dev));
    205207
    206         rtc->boot_time.tv_sec = 0;
    207         rtc->boot_time.tv_usec = 0;
     208        rtc->boottime = 0;
    208209        rtc->clients_connected = 0;
    209210
     
    213214        /* Connect to the parent's driver */
    214215
    215         parent_sess = ddf_dev_parent_sess_create(rtc->dev);
     216        parent_sess = ddf_dev_parent_sess_create(rtc->dev, EXCHANGE_SERIALIZE);
    216217        if (!parent_sess) {
    217218                ddf_msg(LVL_ERROR, "Failed to connect to parent driver\
     
    326327        fibril_mutex_lock(&rtc->mutex);
    327328
    328         if (rtc->boot_time.tv_sec) {
     329        if (rtc->boottime != 0) {
    329330                /* There is no need to read the current time from the
    330331                 * device because it has already been cached.
    331332                 */
    332333
    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
    337336                fibril_mutex_unlock(&rtc->mutex);
    338337
    339                 return time_tv2tm(&curtime, t);
     338                return time_local2tm(cur_time, t);
    340339        }
    341340
     
    346345        }
    347346
    348         /* Microseconds are below RTC's resolution, assume 0. */
    349         t->tm_usec = 0;
    350 
    351347        /* now read the registers */
    352348        do {
    353349                /* 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);
    359354                t->tm_hour = rtc_register_read(rtc, RTC_HOUR);
    360355                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);
    362357                t->tm_year = rtc_register_read(rtc, RTC_YEAR);
    363358
    364359                /* 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) ||
    367362            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) ||
    369364            t->tm_year != rtc_register_read(rtc, RTC_YEAR));
    370365
     
    372367        bool _12h_mode = !(rtc_register_read(rtc, RTC_STATUS_B) &
    373368            RTC_B_24H);
     369
    374370        if (_12h_mode) {
    375371                /* The RTC is working in 12h mode, check if it is AM or PM */
     
    383379        /* Check if the RTC is working in BCD mode */
    384380        bcd_mode = !(rtc_register_read(rtc, RTC_STATUS_B) & RTC_B_BCD);
     381
    385382        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);
    388385                t->tm_hour = bcd2bin(t->tm_hour);
    389386                t->tm_mday = bcd2bin(t->tm_mday);
    390                 t->tm_mon = bcd2bin(t->tm_mon);
     387                t->tm_mon  = bcd2bin(t->tm_mon);
    391388                t->tm_year = bcd2bin(t->tm_year);
    392389        }
     
    418415                result = EINVAL;
    419416        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();
    426418                result = EOK;
    427419        }
     
    444436        bool bcd_mode;
    445437        time_t norm_time;
    446         struct timeval uptime;
    447         struct timeval ntv;
     438        time_t uptime;
    448439        int  reg_b;
    449440        int  reg_a;
     
    455446                return EINVAL;
    456447
    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) {
    462450                /* This is not acceptable */
    463451                return EINVAL;
     
    471459        }
    472460
    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;
    476463
    477464        /* Detect the RTC epoch */
     
    745732}
    746733
     734static time_t
     735uptime_get(void)
     736{
     737        struct timeval tv;
     738
     739        getuptime(&tv);
     740
     741        return tv.tv_sec;
     742}
     743
    747744static int
    748745rtc_fun_online(ddf_fun_t *fun)
Note: See TracChangeset for help on using the changeset viewer.