From patchwork Tue Apr 10 11:49:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 896612 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-rtc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="S7e5lr1t"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40L57g4tlnz9s2Y for ; Tue, 10 Apr 2018 21:49:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752404AbeDJLtu (ORCPT ); Tue, 10 Apr 2018 07:49:50 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:36280 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752373AbeDJLtt (ORCPT ); Tue, 10 Apr 2018 07:49:49 -0400 Received: by mail-pf0-f196.google.com with SMTP id g14so8077414pfh.3 for ; Tue, 10 Apr 2018 04:49:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=12GTGVNjqVsEP+FMzvTrs+Xu5/i/Rslt8b4sgxTKhXQ=; b=S7e5lr1tCPhu/nGNCPfwYj1YfOYxZX1Ba++WHP1wwl/dOu93XOXShvg03sGIJ5x3yD +y5Eq51oYob89kOKgKuAivY5EGGvWy17j6H58ckiddZvQN/0B1QXw5HkUJZ/CThltLPM 7RFFmlZo6jmAfwUAogixfsLwtvAvRqv2+RqF/4e/qjSW/TdyZ4IW7txYjbnmApTzoI6j 9Ym8J2mf3kXROr+RYpy2PCDcSD4YFoLm3I5czYDPL/RJKnvQzng8hPEKuUCaJhNUU7WV z5AZiWehVj24xy9xXQh6l1HWqVzpYmlgwRvi/DN/7/exFVbP9Hojx7GTwVWRF1qallK+ 6gcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=12GTGVNjqVsEP+FMzvTrs+Xu5/i/Rslt8b4sgxTKhXQ=; b=baykqrB558QuDLAkgpa3S2vaS54pgdkxl0BiPDpiUq21YEBQWkMu3qQ5luGpK1PDQD lTT2tKcoN3jRjYzsEKTP115EGSjWK2IZuCADYPnsUBF7vvVOk+WSEgluCZdO9I60sU5B a+kCAdSe4G7WQ0P4H/wBLyD2LFa0p8AxClmR2Z91ri3iVlp6cPzVq9+MjX015KITWG8F LbTfpe1NtKBH5gCEZMFFQJR+/PlrJy54eAF1W89TGxP1PibxGBimMgnOSFZVpofjEBkb LXh6QvgHix7lV1ch3mI+RLOgqIdqf6BI8ta93/75P5VZiQK1zniDojGEM+6v4p8LlQCL tCNA== X-Gm-Message-State: ALQs6tAdq20sy1EtIBG0X1c0DNHEqvWBYQ+6GXlq1v+s/8R4XOjAH9Cv MMQT9rxpL3yHpDcZGVhDCb8= X-Google-Smtp-Source: AIpwx4/KcJfwnOjAxlnklUaKuKlMQQWhZ1ypP0Gn55zIH55LOJ8GEm0ciUKp2jF+Rgo7rnJhZGkslg== X-Received: by 10.98.156.91 with SMTP id f88mr72048pfe.128.1523360989396; Tue, 10 Apr 2018 04:49:49 -0700 (PDT) Received: from roar.au.ibm.com (59-102-70-78.tpgi.com.au. [59.102.70.78]) by smtp.gmail.com with ESMTPSA id v23sm4851002pfn.65.2018.04.10.04.49.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Apr 2018 04:49:48 -0700 (PDT) From: Nicholas Piggin To: linuxppc-dev@lists.ozlabs.org Cc: Nicholas Piggin , Benjamin Herrenschmidt , linux-rtc@vger.kernel.org Subject: [PATCH 2/3] powerpc/powernv: Fix OPAL RTC driver OPAL_BUSY loops Date: Tue, 10 Apr 2018 21:49:32 +1000 Message-Id: <20180410114933.24581-3-npiggin@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180410114933.24581-1-npiggin@gmail.com> References: <20180410114933.24581-1-npiggin@gmail.com> Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org The OPAL RTC driver does not sleep in case it gets OPAL_BUSY or OPAL_BUSY_EVENT from firmware, which causes large scheduling latencies, up to 50 seconds have been observed here when RTC stops responding (BMC reboot can do it). Fix this by converting it to the standard form OPAL_BUSY loop that sleeps. Fixes 628daa8d5abfd ("powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks" Cc: Benjamin Herrenschmidt Cc: linux-rtc@vger.kernel.org Signed-off-by: Nicholas Piggin Acked-by: Alexandre Belloni --- arch/powerpc/platforms/powernv/opal-rtc.c | 8 +++-- drivers/rtc/rtc-opal.c | 37 ++++++++++++++--------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c index f8868864f373..aa2a5139462e 100644 --- a/arch/powerpc/platforms/powernv/opal-rtc.c +++ b/arch/powerpc/platforms/powernv/opal-rtc.c @@ -48,10 +48,12 @@ unsigned long __init opal_get_boot_time(void) while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) + if (rc == OPAL_BUSY_EVENT) { + mdelay(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); - else if (rc == OPAL_BUSY) - mdelay(10); + } else if (rc == OPAL_BUSY) { + mdelay(OPAL_BUSY_DELAY_MS); + } } if (rc != OPAL_SUCCESS) return 0; diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index 304e891e35fc..60f2250fd96b 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -57,7 +57,7 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) { - long rc = OPAL_BUSY; + s64 rc = OPAL_BUSY; int retries = 10; u32 y_m_d; u64 h_m_s_ms; @@ -66,13 +66,17 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) + if (rc == OPAL_BUSY_EVENT) { + msleep(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); - else if (retries-- && (rc == OPAL_HARDWARE - || rc == OPAL_INTERNAL_ERROR)) - msleep(10); - else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT) - break; + } else if (rc == OPAL_BUSY) { + msleep(OPAL_BUSY_DELAY_MS); + } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) { + if (retries--) { + msleep(10); /* Wait 10ms before retry */ + rc = OPAL_BUSY; /* go around again */ + } + } } if (rc != OPAL_SUCCESS) @@ -87,21 +91,26 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm) { - long rc = OPAL_BUSY; + s64 rc = OPAL_BUSY; int retries = 10; u32 y_m_d = 0; u64 h_m_s_ms = 0; tm_to_opal(tm, &y_m_d, &h_m_s_ms); + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_rtc_write(y_m_d, h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) + if (rc == OPAL_BUSY_EVENT) { + msleep(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); - else if (retries-- && (rc == OPAL_HARDWARE - || rc == OPAL_INTERNAL_ERROR)) - msleep(10); - else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT) - break; + } else if (rc == OPAL_BUSY) { + msleep(OPAL_BUSY_DELAY_MS); + } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) { + if (retries--) { + msleep(10); /* Wait 10ms before retry */ + rc = OPAL_BUSY; /* go around again */ + } + } } return rc == OPAL_SUCCESS ? 0 : -EIO;