Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp3387464ybp; Sun, 6 Oct 2019 10:49:12 -0700 (PDT) X-Google-Smtp-Source: APXvYqwZQ6+7MafebFeOi844VPVqeuDUpIMsrL0OLfGGLqaECX9h3mGJChm7gbSyNyTtWEh1yb1r X-Received: by 2002:a50:ea8c:: with SMTP id d12mr25535164edo.87.1570384152239; Sun, 06 Oct 2019 10:49:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570384152; cv=none; d=google.com; s=arc-20160816; b=HhYo/hwzXYPoCTnWArbEIswvL7TGP3cny4th0WUQQqdUkB6duW0HGIKp8EE26eF0Hi 33t7XHPt7vwSoJzLLBZ5hpN0ZMeTv95EsZs+rec2PrI7w6JRtnlHvAoO9Qn6q9zQdy72 wVGn+wafgqTtxLVCVs7MuuhMAUSjcsomTkFSyo3iu7HzHVVnlJXLBuP0qKzd6kIMZ2Pa 1v8TfBKMiZCpgjq2zMeSOvHgSMSEoMUwyvlXpev5dvs97NHLr/jbPX093Fpq2CNXcfzW ssnfYlmku7fU/FMqkKHWqNwd+A0UimZ+tPkTl7hf+ZNgq5JLFM949Lli6LRf28Y8BZty M3rQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=mpzeT0l95+rEPkCLHm9cdeR4cLwaN+lXi1cdL4f5Htg=; b=h+OGaudrx6L083LE3v7eBHoWfcTKJj82Lt/GPutiVETeizJaO0n4v05ZAwfBH6QOsS zeNV12QFfguMhR1vtAsxOYrc+4WkUIEhlEHPJIBXCbbHBT9r60Ghn5fOZ1O/+RnKbJ8h sYXVjQ6uplndShDuj5pEM/gdOh17/8oN4+bN9dn7UaVyOCbhQicsWAz1jR6WW3BvtTmO fQBoJbxuUb89LHlPh/noMnWvIAJKxRvcC3w08vViEF0hE/nwIMECDZ7JBLXr7wssuQP3 8Lq7x5gdbeJMbRH5Sagah9syufgl4dnNGnx3GnGTgwRPiKZrxqWlfqAYNZp4HflE7k4N GQHQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Eckmd8vq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y2si5782074ejw.308.2019.10.06.10.48.48; Sun, 06 Oct 2019 10:49:12 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Eckmd8vq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730957AbfJFRoC (ORCPT + 99 others); Sun, 6 Oct 2019 13:44:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:44086 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727503AbfJFRn7 (ORCPT ); Sun, 6 Oct 2019 13:43:59 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CBB3220700; Sun, 6 Oct 2019 17:43:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570383838; bh=hDhef2aTdq4qR/BBdAQqoM/CUsEQJstjxEaKYJBV94I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Eckmd8vqPSU1FreY5XXVVs+GVy7wXBOarUtfU7aJvWzMS6vTpD2rIJDhIDPlx0Feo l3upWHHISbXBW0X+3wc3wjod7rbILbwz5ngn4YTq4rBp003HSjNVvfU0rh7ljvuXCY Ue26ghzoJEV4pRg/jlYSiTKJLT2NYOD5DCvXI+cg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jon Hunter , Thierry Reding , Wolfram Sang , Sasha Levin Subject: [PATCH 5.3 113/166] i2c: tegra: Move suspend handling to NOIRQ phase Date: Sun, 6 Oct 2019 19:21:19 +0200 Message-Id: <20191006171222.882052155@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191006171212.850660298@linuxfoundation.org> References: <20191006171212.850660298@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jon Hunter [ Upstream commit 8ebf15e9c869e764b3aab4928938ee68c0e2bd6d ] Commit acc8abcb2a9c ("i2c: tegra: Add suspend-resume support") added suspend support for the Tegra I2C driver and following this change on Tegra30 the following WARNING is seen on entering suspend ... WARNING: CPU: 2 PID: 689 at /dvs/git/dirty/git-master_l4t-upstream/kernel/drivers/i2c/i2c-core.h:54 __i2c_transfer+0x35c/0x70c i2c i2c-4: Transfer while suspended Modules linked in: brcmfmac brcmutil CPU: 2 PID: 689 Comm: rtcwake Not tainted 5.3.0-rc7-g089cf7f6ecb2 #1 Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0xb4/0xc8) [] (dump_stack) from [] (__warn+0xe0/0xf8) [] (__warn) from [] (warn_slowpath_fmt+0x48/0x6c) [] (warn_slowpath_fmt) from [] (__i2c_transfer+0x35c/0x70c) [] (__i2c_transfer) from [] (i2c_transfer+0x58/0xf4) [] (i2c_transfer) from [] (i2c_transfer_buffer_flags+0x4c/0x70) [] (i2c_transfer_buffer_flags) from [] (regmap_i2c_write+0x14/0x30) [] (regmap_i2c_write) from [] (_regmap_raw_write_impl+0x35c/0x868) [] (_regmap_raw_write_impl) from [] (_regmap_update_bits+0xe4/0xec) [] (_regmap_update_bits) from [] (regmap_update_bits_base+0x50/0x74) [] (regmap_update_bits_base) from [] (regulator_disable_regmap+0x44/0x54) [] (regulator_disable_regmap) from [] (_regulator_do_disable+0xf8/0x268) [] (_regulator_do_disable) from [] (_regulator_disable+0xf4/0x19c) [] (_regulator_disable) from [] (regulator_disable+0x34/0x64) [] (regulator_disable) from [] (regulator_bulk_disable+0x28/0xb4) [] (regulator_bulk_disable) from [] (tegra_pcie_power_off+0x64/0xa8) [] (tegra_pcie_power_off) from [] (tegra_pcie_pm_suspend+0x25c/0x3f4) [] (tegra_pcie_pm_suspend) from [] (dpm_run_callback+0x38/0x1d4) [] (dpm_run_callback) from [] (__device_suspend_noirq+0xc0/0x2b8) [] (__device_suspend_noirq) from [] (dpm_noirq_suspend_devices+0x100/0x37c) [] (dpm_noirq_suspend_devices) from [] (dpm_suspend_noirq+0x1c/0x48) [] (dpm_suspend_noirq) from [] (suspend_devices_and_enter+0x1d0/0xa00) [] (suspend_devices_and_enter) from [] (pm_suspend+0x220/0x74c) [] (pm_suspend) from [] (state_store+0x6c/0xc8) [] (state_store) from [] (kernfs_fop_write+0xe8/0x1c4) [] (kernfs_fop_write) from [] (__vfs_write+0x2c/0x1c4) [] (__vfs_write) from [] (vfs_write+0xa4/0x184) [] (vfs_write) from [] (ksys_write+0x9c/0xdc) [] (ksys_write) from [] (ret_fast_syscall+0x0/0x54) Exception stack(0xe9f21fa8 to 0xe9f21ff0) 1fa0: 0000006c 004b2438 00000004 004b2438 00000004 00000000 1fc0: 0000006c 004b2438 004b1228 00000004 00000004 00000004 0049e78c 004b1228 1fe0: 00000004 be9809b8 b6f0bc0b b6e96206 The problem is that the Tegra PCIe driver indirectly uses I2C for controlling some regulators and the I2C driver is now being suspended before the PCIe driver causing the PCIe suspend to fail. The Tegra PCIe driver is suspended during the NOIRQ phase and this cannot be changed due to other dependencies. Therefore, we also need to move the suspend handling for the Tegra I2C driver to the NOIRQ phase as well. In order to move the I2C suspend handling to the NOIRQ phase we also need to avoid calling pm_runtime_get/put() because per commit 1e2ef05bb8cf ("PM: Limit race conditions between runtime PM and system sleep (v2)") these cannot be called early in resume. The function tegra_i2c_init(), called during resume, calls pm_runtime_get/put() and so move these calls outside of tegra_i2c_init(), so this function can be used during the NOIRQ resume phase. Fixes: acc8abcb2a9c ("i2c: tegra: Add suspend-resume support") Signed-off-by: Jon Hunter Acked-by: Thierry Reding Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-tegra.c | 40 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 9fcb13beeb8f4..7a3291d91a5ee 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -713,12 +713,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit) u32 tsu_thd; u8 tlow, thigh; - err = pm_runtime_get_sync(i2c_dev->dev); - if (err < 0) { - dev_err(i2c_dev->dev, "runtime resume failed %d\n", err); - return err; - } - reset_control_assert(i2c_dev->rst); udelay(2); reset_control_deassert(i2c_dev->rst); @@ -772,7 +766,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit) if (err) { dev_err(i2c_dev->dev, "failed changing clock rate: %d\n", err); - goto err; + return err; } } @@ -787,23 +781,21 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit) err = tegra_i2c_flush_fifos(i2c_dev); if (err) - goto err; + return err; if (i2c_dev->is_multimaster_mode && i2c_dev->hw->has_slcg_override_reg) i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE); err = tegra_i2c_wait_for_config_load(i2c_dev); if (err) - goto err; + return err; if (i2c_dev->irq_disabled) { i2c_dev->irq_disabled = false; enable_irq(i2c_dev->irq); } -err: - pm_runtime_put(i2c_dev->dev); - return err; + return 0; } static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev) @@ -1616,12 +1608,14 @@ static int tegra_i2c_probe(struct platform_device *pdev) } pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { + if (!pm_runtime_enabled(&pdev->dev)) ret = tegra_i2c_runtime_resume(&pdev->dev); - if (ret < 0) { - dev_err(&pdev->dev, "runtime resume failed\n"); - goto unprepare_div_clk; - } + else + ret = pm_runtime_get_sync(i2c_dev->dev); + + if (ret < 0) { + dev_err(&pdev->dev, "runtime resume failed\n"); + goto unprepare_div_clk; } if (i2c_dev->is_multimaster_mode) { @@ -1666,6 +1660,8 @@ static int tegra_i2c_probe(struct platform_device *pdev) if (ret) goto release_dma; + pm_runtime_put(&pdev->dev); + return 0; release_dma: @@ -1726,17 +1722,25 @@ static int tegra_i2c_resume(struct device *dev) struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); int err; + err = tegra_i2c_runtime_resume(dev); + if (err) + return err; + err = tegra_i2c_init(i2c_dev, false); if (err) return err; + err = tegra_i2c_runtime_suspend(dev); + if (err) + return err; + i2c_mark_adapter_resumed(&i2c_dev->adapter); return 0; } static const struct dev_pm_ops tegra_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume) SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume, NULL) }; -- 2.20.1