From patchwork Sat Mar 7 05:04:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neelesh Gupta X-Patchwork-Id: 447541 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3452714012F for ; Sat, 7 Mar 2015 16:06:49 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 0EB101A0408 for ; Sat, 7 Mar 2015 16:06:49 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e28smtp01.in.ibm.com (e28smtp01.in.ibm.com [122.248.162.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4CBFA1A03B9 for ; Sat, 7 Mar 2015 16:06:45 +1100 (AEDT) Received: from /spool/local by e28smtp01.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sat, 7 Mar 2015 10:36:42 +0530 Received: from d28dlp03.in.ibm.com (9.184.220.128) by e28smtp01.in.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Sat, 7 Mar 2015 10:36:41 +0530 Received: from d28relay04.in.ibm.com (d28relay04.in.ibm.com [9.184.220.61]) by d28dlp03.in.ibm.com (Postfix) with ESMTP id 42A5B125804B for ; Sat, 7 Mar 2015 10:38:05 +0530 (IST) Received: from d28av04.in.ibm.com (d28av04.in.ibm.com [9.184.220.66]) by d28relay04.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t2756ejH131434 for ; Sat, 7 Mar 2015 10:36:40 +0530 Received: from d28av04.in.ibm.com (localhost [127.0.0.1]) by d28av04.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t2756eT5024795 for ; Sat, 7 Mar 2015 10:36:40 +0530 Received: from localhost.localdomain ([9.77.71.203]) by d28av04.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t2756cKa024767 for ; Sat, 7 Mar 2015 10:36:39 +0530 To: skiboot@lists.ozlabs.org From: Neelesh Gupta Date: Sat, 07 Mar 2015 10:34:16 +0530 Message-ID: <20150307050403.32647.48107.stgit@localhost.localdomain> In-Reply-To: <20150307050341.32647.3908.stgit@localhost.localdomain> References: <20150307050341.32647.3908.stgit@localhost.localdomain> User-Agent: StGit/0.16 MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15030705-4790-0000-0000-000006EF25AA Subject: [Skiboot] [PATCH 2/2] fsp/rtc: Introduce the rtc write state machine X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Similar to rtc read requests, have a state machine to handle the write transitions. Signed-off-by: Neelesh Gupta Reviewed-by: Vasant Hegde --- hw/fsp/fsp-rtc.c | 118 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/hw/fsp/fsp-rtc.c b/hw/fsp/fsp-rtc.c index 2c7a592..955521b 100644 --- a/hw/fsp/fsp-rtc.c +++ b/hw/fsp/fsp-rtc.c @@ -68,9 +68,10 @@ static enum { } rtc_tod_state = RTC_TOD_INVALID; /* State machine for getting an RTC request. - * RTC_READ_NO_REQUEST -> RTC_READ_PENDING_REQUEST (one in flight) - * RTC_READ_PENDING_REQUEST -> RTC_READ_REQUEST_AVAILABLE, when FSP responds - * RTC_READ_REQUEST_AVAILABLE -> RTC_READ_NO_REQUEST, + * RTC_{READ/WRITE}_NO_REQUEST -> RTC_{READ/WRITE}_PENDING_REQUEST (one in flight) + * RTC_{READ/WRITE}_PENDING_REQUEST -> RTC_{READ/WRITE}_REQUEST_AVAILABLE, + * when FSP responds + * RTC_{READ/WRITE}_REQUEST_AVAILABLE -> RTC_{READ/WRITE}_NO_REQUEST, * when OS retrieves it */ static enum { @@ -79,7 +80,11 @@ static enum { RTC_READ_REQUEST_AVAILABLE, } rtc_read_request_state = RTC_READ_NO_REQUEST; -static bool rtc_write_in_flight = false; +static enum { + RTC_WRITE_NO_REQUEST, + RTC_WRITE_PENDING_REQUEST, + RTC_WRITE_REQUEST_AVAILABLE, +} rtc_write_request_state = RTC_WRITE_NO_REQUEST; static bool rtc_tod_cache_dirty = false; @@ -200,9 +205,16 @@ static void fsp_rtc_process_read(struct fsp_msg *read_resp) } } -static void opal_rtc_eval_events(void) +static void opal_rtc_eval_events(bool read_write) { - bool request_available = (rtc_read_request_state == RTC_READ_REQUEST_AVAILABLE); + bool request_available; + + if (read_write) + request_available = (rtc_read_request_state == + RTC_READ_REQUEST_AVAILABLE); + else + request_available = (rtc_write_request_state == + RTC_WRITE_REQUEST_AVAILABLE); assert(lock_held_by_me(&rtc_lock)); opal_update_pending_evt(OPAL_EVENT_RTC, @@ -214,12 +226,15 @@ static void fsp_rtc_req_complete(struct fsp_msg *msg) lock(&rtc_lock); prlog(PR_TRACE, "RTC completion %p\n", msg); - if (fsp_msg_cmd(msg) == (FSP_CMD_READ_TOD & 0xffffff)) + if (fsp_msg_cmd(msg) == (FSP_CMD_READ_TOD & 0xffffff)) { fsp_rtc_process_read(msg->resp); - else - rtc_write_in_flight = false; + opal_rtc_eval_events(true); + } else { + assert(rtc_write_request_state == RTC_WRITE_PENDING_REQUEST); + rtc_write_request_state = RTC_WRITE_REQUEST_AVAILABLE; + opal_rtc_eval_events(false); + } - opal_rtc_eval_events(); unlock(&rtc_lock); fsp_freemsg(msg); } @@ -287,7 +302,7 @@ static int64_t fsp_opal_rtc_read(uint32_t *year_month_day, prlog(PR_TRACE, "RTC read complete, state %d\n", rtc_tod_state); rtc_read_request_state = RTC_READ_NO_REQUEST; - opal_rtc_eval_events(); + opal_rtc_eval_events(true); if (rtc_tod_state == RTC_TOD_VALID) { rtc_cache_get_datetime(year_month_day, @@ -319,26 +334,15 @@ out: return rc; } -static int64_t fsp_opal_rtc_write(uint32_t year_month_day, - uint64_t hour_minute_second_millisecond) +static int64_t fsp_rtc_send_write_request(uint32_t year_month_day, + uint64_t hour_minute_second_millisecond) { - struct fsp_msg *rtc_write_msg; + struct fsp_msg *msg; uint32_t w0, w1, w2; - int64_t rc; struct tm tm; - lock(&rtc_lock); - if (rtc_tod_state == RTC_TOD_PERMANENT_ERROR) { - rc = OPAL_HARDWARE; - goto bail; - } - - if (rtc_write_in_flight) { - rc = OPAL_BUSY_EVENT; - goto bail; - } - - prlog(PR_TRACE, "Sending new write request...\n"); + assert(lock_held_by_me(&rtc_lock)); + assert(rtc_write_request_state == RTC_WRITE_NO_REQUEST); /* Create a request and send it. Just like for read, we ignore * the "millisecond" field which is probably supposed to be @@ -348,31 +352,57 @@ static int64_t fsp_opal_rtc_write(uint32_t year_month_day, w1 = (hour_minute_second_millisecond >> 32) & 0xffffff00; w2 = 0; - rtc_write_msg = fsp_mkmsg(FSP_CMD_WRITE_TOD, 3, w0, w1, w2); - if (!rtc_write_msg) { + msg = fsp_mkmsg(FSP_CMD_WRITE_TOD, 3, w0, w1, w2); + if (!msg) { prlog(PR_TRACE, " -> allocation failed !\n"); - rc = OPAL_INTERNAL_ERROR; - goto bail; + return OPAL_INTERNAL_ERROR; } - prlog(PR_TRACE, " -> req at %p\n", rtc_write_msg); + prlog(PR_TRACE, " -> req at %p\n", msg); if (fsp_in_reset) { - datetime_to_tm(rtc_write_msg->data.words[0], - (u64) rtc_write_msg->data.words[1] << 32, &tm); + datetime_to_tm(msg->data.words[0], + (u64) msg->data.words[1] << 32, &tm); rtc_cache_update(&tm); rtc_tod_cache_dirty = true; - rc = OPAL_SUCCESS; - fsp_freemsg(rtc_write_msg); - goto bail; - } else if (fsp_queue_msg(rtc_write_msg, fsp_rtc_req_complete)) { + fsp_freemsg(msg); + return OPAL_SUCCESS; + } else if (fsp_queue_msg(msg, fsp_rtc_req_complete)) { prlog(PR_TRACE, " -> queueing failed !\n"); - rc = OPAL_INTERNAL_ERROR; - fsp_freemsg(rtc_write_msg); - goto bail; + fsp_freemsg(msg); + return OPAL_INTERNAL_ERROR; } - rc = OPAL_BUSY_EVENT; - rtc_write_in_flight = true; - bail: + + rtc_write_request_state = RTC_WRITE_PENDING_REQUEST; + + return OPAL_BUSY_EVENT; +} + +static int64_t fsp_opal_rtc_write(uint32_t year_month_day, + uint64_t hour_minute_second_millisecond) +{ + int rc; + + lock(&rtc_lock); + if (rtc_tod_state == RTC_TOD_PERMANENT_ERROR) { + rc = OPAL_HARDWARE; + 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, + hour_minute_second_millisecond); + } else if (rtc_write_request_state == RTC_WRITE_PENDING_REQUEST) { + rc = OPAL_BUSY_EVENT; + } else { + assert(rtc_write_request_state == RTC_WRITE_REQUEST_AVAILABLE); + rtc_write_request_state = RTC_WRITE_NO_REQUEST; + + opal_rtc_eval_events(false); + rc = OPAL_SUCCESS; + } + +out: unlock(&rtc_lock); return rc; }