aboutsummaryrefslogtreecommitdiff
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-08-18 13:30:38 +1000
commit7cf785f57cdf4276a8f8b3d8e098b2c4deaac2a1 (patch)
treebd662b062f3d229b7bcf4ef68c7e1c5416391f37
parent3a3616da320cfee7f44d974509ab82b08a415c9e (diff)
downloadskiboot-7cf785f57cdf4276a8f8b3d8e098b2c4deaac2a1.zip
skiboot-7cf785f57cdf4276a8f8b3d8e098b2c4deaac2a1.tar.gz
skiboot-7cf785f57cdf4276a8f8b3d8e098b2c4deaac2a1.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>
-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 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,