aboutsummaryrefslogtreecommitdiff
path: root/hw/fsp
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2017-06-13 15:52:34 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-06-14 14:30:31 +1000
commitf4757fbfcf616365c74b1aa6508b2ab27480cdd0 (patch)
treee9e6f5813e07b8b101906978d58419e1636a11ea /hw/fsp
parent447ccc4de529f001271fd4dfd78401bc4c90832e (diff)
downloadskiboot-f4757fbfcf616365c74b1aa6508b2ab27480cdd0.zip
skiboot-f4757fbfcf616365c74b1aa6508b2ab27480cdd0.tar.gz
skiboot-f4757fbfcf616365c74b1aa6508b2ab27480cdd0.tar.bz2
FSP/RTC: Fix possible FSP R/R issue in rtc write path
fsp_opal_rtc_write() checks FSP status before queueing message to FSP. But if FSP R/R starts before getting response to queued message then we will continue to return OPAL_BUSY_EVENT to host. In some extreme condition host may experience hang. Once FSP is back we will repost message, get response from FSP and return OPAL_SUCCES to host. This patch caches new values and returns OPAL_SUCCESS if FSP R/R is happening. And once FSP is back we will send cached value to FSP. Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/fsp')
-rw-r--r--hw/fsp/fsp-rtc.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/hw/fsp/fsp-rtc.c b/hw/fsp/fsp-rtc.c
index b41e295..8ee0f5a 100644
--- a/hw/fsp/fsp-rtc.c
+++ b/hw/fsp/fsp-rtc.c
@@ -342,7 +342,6 @@ static int64_t fsp_rtc_send_write_request(uint32_t year_month_day,
{
struct fsp_msg *msg;
uint32_t w0, w1, w2;
- struct tm tm;
assert(lock_held_by_me(&rtc_lock));
assert(rtc_write_request_state == RTC_WRITE_NO_REQUEST);
@@ -362,14 +361,7 @@ static int64_t fsp_rtc_send_write_request(uint32_t year_month_day,
}
prlog(PR_TRACE, " -> req at %p\n", msg);
- if (fsp_in_rr()) {
- datetime_to_tm(msg->data.words[0],
- (u64) msg->data.words[1] << 32, &tm);
- rtc_cache_update(&tm);
- rtc_tod_cache_dirty = true;
- fsp_freemsg(msg);
- return OPAL_SUCCESS;
- } else if (fsp_queue_msg(msg, fsp_rtc_req_complete)) {
+ if (fsp_queue_msg(msg, fsp_rtc_req_complete)) {
prlog(PR_TRACE, " -> queueing failed !\n");
fsp_freemsg(msg);
return OPAL_INTERNAL_ERROR;
@@ -384,6 +376,7 @@ static int64_t fsp_opal_rtc_write(uint32_t year_month_day,
uint64_t hour_minute_second_millisecond)
{
int rc;
+ struct tm tm;
lock(&rtc_lock);
if (rtc_tod_state == RTC_TOD_PERMANENT_ERROR) {
@@ -391,6 +384,15 @@ static int64_t fsp_opal_rtc_write(uint32_t year_month_day,
goto out;
}
+ if (fsp_in_rr()) {
+ datetime_to_tm(year_month_day,
+ hour_minute_second_millisecond, &tm);
+ rtc_cache_update(&tm);
+ rtc_tod_cache_dirty = true;
+ rc = OPAL_SUCCESS;
+ goto out;
+ }
+
if (rtc_write_request_state == RTC_WRITE_NO_REQUEST) {
prlog(PR_TRACE, "Sending new RTC write request\n");
rc = fsp_rtc_send_write_request(year_month_day,