Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp2579293pxb; Tue, 21 Sep 2021 03:05:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyRcxHSVhjy0AteWe0uH41eqCS+9ZT+KBvgV+jqRcxxwGrV6SP9P3xnsyqQfaLMKnMOsnCh X-Received: by 2002:a17:906:645:: with SMTP id t5mr34086280ejb.163.1632218749162; Tue, 21 Sep 2021 03:05:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632218749; cv=none; d=google.com; s=arc-20160816; b=kEylj8LDbPJPBH5YXo2U+5lql4Qs86bSuw2Yd36+GBlKCTINx1k5wvHObmNguaCPc7 owvK3X6oqOaNm5i23MIQj51QssVVUPXNBm/zmFHbB/m6dedVUTcI1F58+sxkKpNIdiWQ FXxGPmtqM5MamUxRBE930rs4HFB09W0BMDFpswVra/12XOtDB4UXGNm7lOskZEo/RiAT qGHPBQnJtTDiQFPpbPVSVEmU0KiejChV7EcBbqC1+OHezq/L5YWFVWoVpWDbPvLRpw8n 36YmXpPlbTejYXV66ibppwH6MC08h0iiq44sOSc6BVQXDgH9nafMWQoms86F7fev8jI7 ShZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=uraNNaJcCAwpp5XUwFKh7ZrwO+PDGXn94kH6soM0lnk=; b=RR1SYuKBWIs8uLRfyKVD66Lrf+F1hEmSLo55mqeTfGn7hg2xJpHWB+9NojrqawmNgp /ynKGVAV0Npk7xdSSx4/0AZNQreL5DhgJdrA9X4ifD/Txz2E1xmHdc4bkRMaPL/0IbxF RtPmYW4CDCk0D+83NnV1Q6rpFptnwvOPmN0kjj+LNQVsQ84hvlOPgUPmkpNATKvsou+k novYiyfSahCwamIVkVex8EOr1yBSCxmk2GkxGBB0XZNmHtcVrcxN9NEKa8+R4lKJiRYz lhgE5H8f5WimWv1GEMuI49l5DbaHXX3LGLbhr8YIfU3udaisFTEZEDhdVQq95q+AB5g2 7txA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l4si27212549edj.282.2021.09.21.03.05.22; Tue, 21 Sep 2021 03:05:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231590AbhIUKDC (ORCPT + 99 others); Tue, 21 Sep 2021 06:03:02 -0400 Received: from muru.com ([72.249.23.125]:35410 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231483AbhIUKC5 (ORCPT ); Tue, 21 Sep 2021 06:02:57 -0400 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 959BA812F; Tue, 21 Sep 2021 10:01:55 +0000 (UTC) From: Tony Lindgren To: linux-omap@vger.kernel.org Cc: Dave Gerlach , Faiz Abbas , Greg Kroah-Hartman , Grygorii Strashko , Keerthy , Kevin Hilman , Nishanth Menon , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/9] bus: ti-sysc: Check for lost context in sysc_reinit_module() Date: Tue, 21 Sep 2021 13:01:08 +0300 Message-Id: <20210921100115.59865-3-tony@atomide.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210921100115.59865-1-tony@atomide.com> References: <20210921100115.59865-1-tony@atomide.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There is no need to restore context if it was not lost. Let's add a new function sysc_check_context() to check for lost context. To make use of it, we need to save the sysconfig register status on enable and disable. Signed-off-by: Tony Lindgren --- drivers/bus/ti-sysc.c | 60 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -132,6 +132,7 @@ struct sysc { struct ti_sysc_cookie cookie; const char *name; u32 revision; + u32 sysconfig; unsigned int reserved:1; unsigned int enabled:1; unsigned int needs_resume:1; @@ -1135,7 +1136,8 @@ static int sysc_enable_module(struct device *dev) best_mode = fls(ddata->cfg.midlemodes) - 1; if (best_mode > SYSC_IDLE_MASK) { dev_err(dev, "%s: invalid midlemode\n", __func__); - return -EINVAL; + error = -EINVAL; + goto save_context; } if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY) @@ -1153,13 +1155,16 @@ static int sysc_enable_module(struct device *dev) sysc_write_sysconfig(ddata, reg); } - /* Flush posted write */ - sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + error = 0; + +save_context: + /* Save context and flush posted write */ + ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); if (ddata->module_enable_quirk) ddata->module_enable_quirk(ddata); - return 0; + return error; } static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode) @@ -1216,8 +1221,10 @@ static int sysc_disable_module(struct device *dev) set_sidle: /* Set SIDLE mode */ idlemodes = ddata->cfg.sidlemodes; - if (!idlemodes || regbits->sidle_shift < 0) - return 0; + if (!idlemodes || regbits->sidle_shift < 0) { + ret = 0; + goto save_context; + } if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE) { best_mode = SYSC_IDLE_FORCE; @@ -1225,7 +1232,8 @@ static int sysc_disable_module(struct device *dev) ret = sysc_best_idle_mode(idlemodes, &best_mode); if (ret) { dev_err(dev, "%s: invalid sidlemode\n", __func__); - return ret; + ret = -EINVAL; + goto save_context; } } @@ -1236,10 +1244,13 @@ static int sysc_disable_module(struct device *dev) reg |= 1 << regbits->autoidle_shift; sysc_write_sysconfig(ddata, reg); - /* Flush posted write */ - sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + ret = 0; - return 0; +save_context: + /* Save context and flush posted write */ + ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + + return ret; } static int __maybe_unused sysc_runtime_suspend_legacy(struct device *dev, @@ -1377,13 +1388,40 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev) return error; } +/* + * Checks if device context was lost. Assumes the sysconfig register value + * after lost context is different from the configured value. Only works for + * enabled devices. + * + * Eventually we may want to also add support to using the context lost + * registers that some SoCs have. + */ +static int sysc_check_context(struct sysc *ddata) +{ + u32 reg; + + if (!ddata->enabled) + return -ENODATA; + + reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + if (reg == ddata->sysconfig) + return 0; + + return -EACCES; +} + static int sysc_reinit_module(struct sysc *ddata, bool leave_enabled) { struct device *dev = ddata->dev; int error; - /* Disable target module if it is enabled */ if (ddata->enabled) { + /* Nothing to do if enabled and context not lost */ + error = sysc_check_context(ddata); + if (!error) + return 0; + + /* Disable target module if it is enabled */ error = sysc_runtime_suspend(dev); if (error) dev_warn(dev, "reinit suspend failed: %i\n", error); -- 2.33.0