diff options
author | Alistair Popple <alistair@popple.id.au> | 2014-11-13 17:16:01 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2014-12-02 18:38:04 +1100 |
commit | eaf4cd02d38946a701f2174b9b8d44156e006eaf (patch) | |
tree | d3fa5ffc5ce7c4a18460801193064c568689530f /core/rtc.c | |
parent | 5819941efc10da9ddf9ce18f6249385eeebcaa6b (diff) | |
download | skiboot-eaf4cd02d38946a701f2174b9b8d44156e006eaf.zip skiboot-eaf4cd02d38946a701f2174b9b8d44156e006eaf.tar.gz skiboot-eaf4cd02d38946a701f2174b9b8d44156e006eaf.tar.bz2 |
rtc: Add a generic rtc cache
Some of the generic skiboot code needs access to the rtc (for example
the pel logging code). Currently this is accessed via a call to fsp
specific code which implements an rtc cache. Obviously this wont work
on systems without a fsp.
This patch makes the rtc cache generic so that we can get the time on
other platforms (assuming they have some kind of rtc).
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/rtc.c')
-rw-r--r-- | core/rtc.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/core/rtc.c b/core/rtc.c new file mode 100644 index 0000000..60d2d85 --- /dev/null +++ b/core/rtc.c @@ -0,0 +1,69 @@ +/* Copyright 2013-2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <skiboot.h> +#include <lock.h> +#include <rtc.h> +#include <timebase.h> + +static struct lock rtc_tod_lock = LOCK_UNLOCKED; + +static struct { + struct tm tm; + unsigned long tb; + bool valid; +} rtc_tod_cache; + +void rtc_cache_update(struct tm *tm) +{ + lock(&rtc_tod_lock); + rtc_tod_cache.tb = mftb(); + rtc_tod_cache.tm = *tm; + rtc_tod_cache.valid = true; + unlock(&rtc_tod_lock); +} + +int rtc_cache_get(struct tm *tm) +{ + unsigned long cache_age_sec; + + lock(&rtc_tod_lock); + if (!rtc_tod_cache.valid) + return -1; + + cache_age_sec = tb_to_msecs(mftb() - rtc_tod_cache.tb) / 1000; + *tm = rtc_tod_cache.tm; + unlock(&rtc_tod_lock); + + tm->tm_sec += cache_age_sec; + mktime(tm); + + return 0; +} + +int rtc_cache_get_datetime(uint32_t *year_month_day, + uint64_t *hour_minute_second_millisecond) +{ + struct tm tm; + + if (rtc_cache_get(&tm) < 0) + return -1; + + tm_to_datetime(&tm, year_month_day, hour_minute_second_millisecond); + + return 0; +} |