diff options
author | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2017-06-13 15:52:34 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-06-14 15:58:19 +1000 |
commit | 79a78d3d8ba61033e6f9084c4519ada1588ebbe1 (patch) | |
tree | 72f3af4d1903f2a7c4e5ede6c4afa81d097ffd1f /hw/fsp | |
parent | bec5e69e8d9a8740ecb7842c8c551651a40bde89 (diff) | |
download | skiboot-79a78d3d8ba61033e6f9084c4519ada1588ebbe1.zip skiboot-79a78d3d8ba61033e6f9084c4519ada1588ebbe1.tar.gz skiboot-79a78d3d8ba61033e6f9084c4519ada1588ebbe1.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>
(cherry picked from commit f4757fbfcf616365c74b1aa6508b2ab27480cdd0)
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/fsp')
-rw-r--r-- | hw/fsp/fsp-rtc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/hw/fsp/fsp-rtc.c b/hw/fsp/fsp-rtc.c index b908ce9..0a67267 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, |