From eaf4cd02d38946a701f2174b9b8d44156e006eaf Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Thu, 13 Nov 2014 17:16:01 +1100 Subject: 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 Signed-off-by: Stewart Smith --- core/rtc.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 core/rtc.c (limited to 'core/rtc.c') 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 +#include +#include +#include + +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; +} -- cgit v1.1