From patchwork Thu Dec 12 23:34:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 1208904 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-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="gmMjsAz2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47Yqsl3PMfz9sQp for ; Fri, 13 Dec 2019 10:35:23 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731347AbfLLXfV (ORCPT ); Thu, 12 Dec 2019 18:35:21 -0500 Received: from mail-lf1-f65.google.com ([209.85.167.65]:45171 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730868AbfLLXfN (ORCPT ); Thu, 12 Dec 2019 18:35:13 -0500 Received: by mail-lf1-f65.google.com with SMTP id 203so541039lfa.12; Thu, 12 Dec 2019 15:35:10 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=cofkplfJ+UfVuDUPTc+Z2SHSyUS2hYt1uSHcs31t8C4=; b=gmMjsAz2nSCvCNEEm1fZ8dksHyNFZmufMXdbWOzni5CZLca4c9ixVBpdNEOYgj7DSm 4AuSrkYYpPQ0sP+A+K9Mh361jz7ABmK5Izkul1zap1adBdZTpvSU7BiTCER5rWiMpkrm 9QE5vLyWLiK0s5EzbYj55S+ZhTTYeklUP6816zyxLjdQxEFwWK/Ik7w4tZcQXR6ZFSat SgCHMA0wkmKoLgpGq0AmquI0Ie1UyG3URjWBMa7JcnE4e4QSP+b4nlSzFj+AwoDK2z5e omDZqn9OZXSMwejdzpfdjlsXn/NNuhgOBKYNvJ6z5pSnTIF9UkUPtEond3SmC2TyoGiZ I6cA== 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:mime-version:content-transfer-encoding; bh=cofkplfJ+UfVuDUPTc+Z2SHSyUS2hYt1uSHcs31t8C4=; b=IODWwWgEcwCy7u5jZs8LLnZtXJfR7V03N5aTWV3lgUZqODyQV/cBY0oqkpL+YLN8jP qZ8hb/mYwC5aZrTYTTkJ9kNorm51gGz3o7RCjO10H8yIu50YTjLymo7dt0u166q8jxB4 sQ7WDfE3kWyLC4P6t83Cv7uspKsqIsw6KSbrAzUVVcm0hd2EnAAxyWNNDP3qLe7SHl1I uzZ2PT/68mdZt3KoI7oa/DbrIURd1UCgDXb2lPYt9Cs/N8Cv53ozK4sy6AmlWQxUIZoc VjayoYcLv4wv/y637vlJN60I6sUtAmxg4K/n6kv7o5jdAyjsgXrCcWbDzmqLoKCFxUEe Kwrg== X-Gm-Message-State: APjAAAW5RPPjVtWTLFkQ/WNqhRL5L+nW9aRsVUyLHtJuYPGj1n/0mNiu Xz1T6Cy8g1323WVVo3tmcWI= X-Google-Smtp-Source: APXvYqy4wT/jfAQX40pfdxu4uKgTXMtqmnPuDHO7thzfZ5wbSdPazJ6xTUey2mwCrGaQHMFqbrEBYw== X-Received: by 2002:a19:7015:: with SMTP id h21mr7012401lfc.68.1576193709738; Thu, 12 Dec 2019 15:35:09 -0800 (PST) Received: from localhost.localdomain (79-139-233-37.dynamic.spd-mgts.ru. [79.139.233.37]) by smtp.gmail.com with ESMTPSA id q27sm3764283ljm.25.2019.12.12.15.35.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Dec 2019 15:35:09 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Laxman Dewangan , Wolfram Sang Cc: linux-i2c@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 1/3] i2c: tegra: Support atomic transfers Date: Fri, 13 Dec 2019 02:34:26 +0300 Message-Id: <20191212233428.14648-2-digetx@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191212233428.14648-1-digetx@gmail.com> References: <20191212233428.14648-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org System shutdown may happen with interrupts being disabled and in this case I2C core rejects transfers if atomic transfer isn't supported by driver. There were several occurrences where I found my Nexus 7 completely discharged despite of being turned off and then one day I spotted this in the log: reboot: Power down ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at drivers/i2c/i2c-core.h:40 i2c_transfer+0x95/0x9c No atomic I2C transfer handler for 'i2c-1' Modules linked in: tegra30_devfreq CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 5.4.0-next-20191202-00120-gf7ecd80fb803-dirty #3195 Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x11/0x14) [] (show_stack) from [] (dump_stack+0x85/0x94) [] (dump_stack) from [] (__warn+0xc1/0xc4) [] (__warn) from [] (warn_slowpath_fmt+0x61/0x78) [] (warn_slowpath_fmt) from [] (i2c_transfer+0x95/0x9c) [] (i2c_transfer) from [] (regmap_i2c_read+0x4d/0x6c) [] (regmap_i2c_read) from [] (_regmap_raw_read+0x99/0x1cc) [] (_regmap_raw_read) from [] (_regmap_bus_read+0x23/0x38) [] (_regmap_bus_read) from [] (_regmap_read+0x3d/0xfc) [] (_regmap_read) from [] (_regmap_update_bits+0x87/0xc4) [] (_regmap_update_bits) from [] (regmap_update_bits_base+0x39/0x50) [] (regmap_update_bits_base) from [] (max77620_pm_power_off+0x29/0x2c) [] (max77620_pm_power_off) from [] (__do_sys_reboot+0xe9/0x170) [] (__do_sys_reboot) from [] (ret_fast_syscall+0x1/0x28) Exception stack(0xde907fa8 to 0xde907ff0) 7fa0: 00000000 00000000 fee1dead 28121969 4321fedc 00000000 7fc0: 00000000 00000000 00000000 00000058 00000000 00000000 00000000 00000000 7fe0: 0045adf0 bed9abb8 004444a0 b6c666d0 ---[ end trace bdd18f87595b1a5e ]--- The atomic transferring is implemented by enforcing PIO mode for the transfer and by polling interrupt status until transfer is completed or failed. Now system shuts down properly every time. Signed-off-by: Dmitry Osipenko Tested-by: Thierry Reding --- drivers/i2c/busses/i2c-tegra.c | 95 +++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index a98bf31d0e5c..799c343571bc 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +249,7 @@ struct tegra_i2c_hw_feature { * @dma_buf_size: DMA buffer size * @is_curr_dma_xfer: indicates active DMA transfer * @dma_complete: DMA completion notifier + * @is_curr_atomic_xfer: indicates active atomic transfer */ struct tegra_i2c_dev { struct device *dev; @@ -279,6 +281,7 @@ struct tegra_i2c_dev { unsigned int dma_buf_size; bool is_curr_dma_xfer; struct completion dma_complete; + bool is_curr_atomic_xfer; }; static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, @@ -999,6 +1002,44 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, i2c_writel(i2c_dev, val, reg); } +static unsigned long +tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev, + unsigned int timeout_ms) +{ + ktime_t ktime = ktime_get(); + ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms); + + do { + u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS); + + if (status) { + tegra_i2c_isr(i2c_dev->irq, i2c_dev); + + if (completion_done(&i2c_dev->msg_complete)) { + s64 delta = ktime_ms_delta(ktimeout, ktime); + + return msecs_to_jiffies(delta) ?: 1; + } + } + + ktime = ktime_get(); + + } while (ktime_before(ktime, ktimeout)); + + return 0; +} + +static unsigned long +tegra_i2c_wait_msg_completion_timeout(struct tegra_i2c_dev *i2c_dev, + unsigned int timeout_ms) +{ + if (i2c_dev->is_curr_atomic_xfer) + return tegra_i2c_poll_completion_timeout(i2c_dev, timeout_ms); + + return wait_for_completion_timeout(&i2c_dev->msg_complete, + msecs_to_jiffies(timeout_ms)); +} + static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap) { struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); @@ -1020,8 +1061,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap) i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG); tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE); - time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, - msecs_to_jiffies(50)); + time_left = tegra_i2c_wait_msg_completion_timeout(i2c_dev, 50); if (time_left == 0) { dev_err(i2c_dev->dev, "timed out for bus clear\n"); return -ETIMEDOUT; @@ -1066,7 +1106,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD); i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_MAX_LEN) && - i2c_dev->dma_buf; + i2c_dev->dma_buf && + !i2c_dev->is_curr_atomic_xfer; tegra_i2c_config_fifo_trig(i2c_dev, xfer_size); dma = i2c_dev->is_curr_dma_xfer; /* @@ -1202,8 +1243,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, i2c_dev->tx_dma_chan); } - time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, - msecs_to_jiffies(xfer_time)); + time_left = tegra_i2c_wait_msg_completion_timeout(i2c_dev, xfer_time); tegra_i2c_mask_irq(i2c_dev, int_mask); if (time_left == 0) { @@ -1270,6 +1310,45 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], return ret ?: i; } +static int tegra_i2c_xfer_atomic(struct i2c_adapter *adap, + struct i2c_msg msgs[], int num) +{ + struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); + int ret; + + i2c_dev->is_curr_atomic_xfer = true; + + /* sanity check that shouldn't fail ever */ + WARN_ON_ONCE(i2c_dev->irq_disabled); + + /* + * Hardware interrupt could be handled by a sibling CPU core, + * while interrupts are disabled only for the current CPU. Thus + * I2C interrupt needs to be disabled globally in order to avoid + * interrupt-handler clashes. + */ + if (!i2c_dev->irq_disabled) { + disable_irq_nosync(i2c_dev->irq); + i2c_dev->irq_disabled = true; + } + + ret = tegra_i2c_xfer(adap, msgs, num); + + /* + * Interrupt will be enabled after hardware reset which happens in + * a case of transfer failure. For successful transfers interrupt + * needs to be re-enabled. + */ + if (i2c_dev->irq_disabled) { + enable_irq(i2c_dev->irq); + i2c_dev->irq_disabled = false; + } + + i2c_dev->is_curr_atomic_xfer = false; + + return ret; +} + static u32 tegra_i2c_func(struct i2c_adapter *adap) { struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); @@ -1297,8 +1376,9 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev) } static const struct i2c_algorithm tegra_i2c_algo = { - .master_xfer = tegra_i2c_xfer, - .functionality = tegra_i2c_func, + .master_xfer = tegra_i2c_xfer, + .master_xfer_atomic = tegra_i2c_xfer_atomic, + .functionality = tegra_i2c_func, }; /* payload size is only 12 bit */ @@ -1607,6 +1687,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) goto unprepare_fast_clk; } + pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) ret = tegra_i2c_runtime_resume(&pdev->dev); From patchwork Thu Dec 12 23:34:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 1208899 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-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="qvoQ62DK"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47Yqsc3L5Nz9sPT for ; Fri, 13 Dec 2019 10:35:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731300AbfLLXfN (ORCPT ); Thu, 12 Dec 2019 18:35:13 -0500 Received: from mail-lj1-f196.google.com ([209.85.208.196]:39152 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730979AbfLLXfN (ORCPT ); Thu, 12 Dec 2019 18:35:13 -0500 Received: by mail-lj1-f196.google.com with SMTP id e10so569139ljj.6; Thu, 12 Dec 2019 15:35:11 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=1cVsLJFz89Vu7CJdRahLgph9ywbohEGqsx2SWyRDeTQ=; b=qvoQ62DKFza17wtpugsAb+eXLIKAXhiZjbSwnk4o3pFzMdgApDHILny97csQi2n2D6 s+XKapMvMMDYIm+GmKYFp2fO8ID+v+qAqukQw0ruC9gM5YwZAJub4g1inJQpq8sEnHat ZZIorWo/dNBekYGecksgzlGYfe4T5LRRhOWq97i9CVHIfA1RqwqapReypOtF+ZZMEScL Qoakwl3sky70ppEFv+GJpEe8w8CSYq5N5QDmCpMhhbhnSw0mgmxL5HBxPAsR6zy829pq 2YIhFrED5+dFTwHt4sxFkDEvcgzRlfD5PQUja4wqAbOWKXLq8DGXom0OrD3ijIMLKcVt K4BQ== 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:mime-version:content-transfer-encoding; bh=1cVsLJFz89Vu7CJdRahLgph9ywbohEGqsx2SWyRDeTQ=; b=kVJX3bmrBHIKJuQgQ3MItcDt62hrM1rrHqNG4amcaz7Z5IFtL64Zjs8m6MgQ7/A4fj KSZc+bhN4TUa4LRUS+7tpSo0oFb/BQjP8hOEL6wZ77xqLaliO/7+kNQhi8dUHtmosgRT umenvC+nECgjYSYmdC41D/ku5bilsbJu/k03OyoidPGg7+00UWCqBpsyCvWmGJbLOx4x AZ8Gdoqq5aVi4FY2vVgUWaBs0SB5FK+JJQuaWYK6ItPWIK00g9iF06xkNaTTm1aJfKtk o6anZPV9mBbPtTEA7EnMAnyo7DPaH3kLYNSYeuywh1CFUIoZxp5/bHJ9+lYCSzP33g7S B6Cg== X-Gm-Message-State: APjAAAXMbgWtwvrhE+DoT89C6mJIxnNveyxG9CjvlXJpv3njwXga5dVs ZQY7ivoVOZXAPGLjK1XtrK8= X-Google-Smtp-Source: APXvYqyjZO5T9LxNXzegg/i9RFDt2Dlhrdk0GASmx5EGlwGUoNiJdI2G95w6Qn1Q9DskdAc/wE1LNA== X-Received: by 2002:a2e:9b58:: with SMTP id o24mr7585247ljj.197.1576193710577; Thu, 12 Dec 2019 15:35:10 -0800 (PST) Received: from localhost.localdomain (79-139-233-37.dynamic.spd-mgts.ru. [79.139.233.37]) by smtp.gmail.com with ESMTPSA id q27sm3764283ljm.25.2019.12.12.15.35.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Dec 2019 15:35:10 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Laxman Dewangan , Wolfram Sang Cc: linux-i2c@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 2/3] i2c: tegra: Rename I2C_PIO_MODE_MAX_LEN to I2C_PIO_MODE_PREFERRED_LEN Date: Fri, 13 Dec 2019 02:34:27 +0300 Message-Id: <20191212233428.14648-3-digetx@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191212233428.14648-1-digetx@gmail.com> References: <20191212233428.14648-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org DMA is preferred for a larger transfers, while PIO is preferred for a smaller transfers to avoid unnecessary DMA overhead. There is no strict size limitations for the PIO-mode transfers, so let's rename the constant for clarity. Signed-off-by: Dmitry Osipenko Tested-by: Thierry Reding --- drivers/i2c/busses/i2c-tegra.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 799c343571bc..b3ecdd87e91f 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -130,11 +130,10 @@ #define I2C_PACKET_HEADER_SIZE 12 /* - * Upto I2C_PIO_MODE_MAX_LEN bytes, controller will use PIO mode, - * above this, controller will use DMA to fill FIFO. - * MAX PIO len is 20 bytes excluding packet header. + * Up to 32 bytes, controller will use PIO mode, above this, controller will + * use DMA to fill FIFO. MAX PIO length is 20 bytes (excluding packet header). */ -#define I2C_PIO_MODE_MAX_LEN 32 +#define I2C_PIO_MODE_PREFERRED_LEN 32 /* * msg_end_type: The bus control which need to be send at end of transfer. @@ -1105,7 +1104,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, xfer_size = msg->len + I2C_PACKET_HEADER_SIZE; xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD); - i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_MAX_LEN) && + i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_PREFERRED_LEN) && i2c_dev->dma_buf && !i2c_dev->is_curr_atomic_xfer; tegra_i2c_config_fifo_trig(i2c_dev, xfer_size); From patchwork Thu Dec 12 23:34:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 1208901 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-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="VhHKdukW"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47Yqsg5F58z9sPn for ; Fri, 13 Dec 2019 10:35:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731320AbfLLXfP (ORCPT ); Thu, 12 Dec 2019 18:35:15 -0500 Received: from mail-lf1-f65.google.com ([209.85.167.65]:38535 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726427AbfLLXfO (ORCPT ); Thu, 12 Dec 2019 18:35:14 -0500 Received: by mail-lf1-f65.google.com with SMTP id r14so569009lfm.5; Thu, 12 Dec 2019 15:35:12 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=aO85qqdL2qrngMuzPa0x+Jh/Nqd2OFRkhn4wziOGIHI=; b=VhHKdukWWAl0HfgdTVlu+e+gJekUvy8NWwa4sOZgVoGH/BGdRJa1E04dIJgHW3EBVu gKUjcyt9LLYQ6PSObvsPJxyPqrlZ7Hc6WiIGqU6RVdSJe3mYVzpAKTbWP99AgMcETNIa 3THlPU1k4Cox+e3Seih+r4md/pJ1z3Ve+NpNz9fkyoOKSfnasMAlH7yGn7e7HSWS/cNO +DGDJfrRLJ6G8JvCo7d17u7wxGBgKlSQa8W2NXFJuG7SB61CKWXlSZy51JmxOTuVTYgG ZaEPRfG8EM+9hYzhlbSTKedU1XdpLJrOwrh3ZONPyTZ+tkEnnN/nIS9JSKG2dSlbZHEH Noiw== 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:mime-version:content-transfer-encoding; bh=aO85qqdL2qrngMuzPa0x+Jh/Nqd2OFRkhn4wziOGIHI=; b=hwurfULxS5BYQrfKt7QUuA2C+ph6OlryxRknQNEqxcVn93avD+mRq097hcEoYxy34M qrODhyu1u+WHRUvyZkCC905lAHTJOIx4QtGM0QWMSfdTZaUkko5qgBpvScZlzg5QYcvK eD3EYMULvqDFL4Y3YfibkhMswMcvAoVlLfDDTyjV4qtV2OGDk7tWyaSK2IfFifztgdPu rl1P03uQa0gCfV3IqpGVp1sGBl7qFizFFKmZDVMUbFd5LraozFObwDpywo9g8bigWD4p MguFLnf4m47wW5kxnD4wYxSoq6cjLSuedfI1NlAWdOMRvglXmIDOaIsoVGVncEYTVayS PjPQ== X-Gm-Message-State: APjAAAXstgshLEqkQqnPnm+WjplgHo8Co4q0Maoa9KibNnrCepbxjarq EakX0IJekIJswBcVC3GbR9o= X-Google-Smtp-Source: APXvYqwxBrytrV61kYH19ZVGWsUDa7/qZ5Ys6fgRynMwL6Xtk/yXgq02a0rkTlDCqLm8dRSqToQdDg== X-Received: by 2002:ac2:44a3:: with SMTP id c3mr7189472lfm.1.1576193711543; Thu, 12 Dec 2019 15:35:11 -0800 (PST) Received: from localhost.localdomain (79-139-233-37.dynamic.spd-mgts.ru. [79.139.233.37]) by smtp.gmail.com with ESMTPSA id q27sm3764283ljm.25.2019.12.12.15.35.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Dec 2019 15:35:11 -0800 (PST) From: Dmitry Osipenko To: Thierry Reding , Jonathan Hunter , Laxman Dewangan , Wolfram Sang Cc: linux-i2c@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 3/3] i2c: tegra: Fix suspending in active runtime PM state Date: Fri, 13 Dec 2019 02:34:28 +0300 Message-Id: <20191212233428.14648-4-digetx@gmail.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191212233428.14648-1-digetx@gmail.com> References: <20191212233428.14648-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org I noticed that sometime I2C clock is kept enabled during suspend-resume. This happens because runtime PM defers dynamic suspension and thus it may happen that runtime PM is in active state when system enters into suspend. In particular I2C controller that is used for CPU's DVFS is often kept ON during suspend because CPU's voltage scaling happens quite often. Note: we marked runtime PM as IRQ-safe during the driver's probe in the "Support atomic transfers" patch, thus it's okay to enforce runtime PM suspend/resume in the NOIRQ phase which is used for the system-level suspend/resume of the driver. Signed-off-by: Dmitry Osipenko --- drivers/i2c/busses/i2c-tegra.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index b3ecdd87e91f..d309a314f4d6 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -1790,9 +1790,14 @@ static int tegra_i2c_remove(struct platform_device *pdev) static int __maybe_unused tegra_i2c_suspend(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); + int err; i2c_mark_adapter_suspended(&i2c_dev->adapter); + err = pm_runtime_force_suspend(dev); + if (err < 0) + return err; + return 0; } @@ -1813,6 +1818,10 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev) if (err) return err; + err = pm_runtime_force_resume(dev); + if (err < 0) + return err; + i2c_mark_adapter_resumed(&i2c_dev->adapter); return 0;