From patchwork Mon Sep 25 21:10:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 9970503 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8C208602D8 for ; Mon, 25 Sep 2017 21:19:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D2BB28DA6 for ; Mon, 25 Sep 2017 21:19:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 71C2528DB8; Mon, 25 Sep 2017 21:19:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 032D628DA3 for ; Mon, 25 Sep 2017 21:19:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935589AbdIYVTS (ORCPT ); Mon, 25 Sep 2017 17:19:18 -0400 Received: from cloudserver094114.home.net.pl ([79.96.170.134]:42978 "EHLO cloudserver094114.home.net.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932182AbdIYVTS (ORCPT ); Mon, 25 Sep 2017 17:19:18 -0400 Received: from 79.184.252.54.ipv4.supernova.orange.pl (79.184.252.54) (HELO aspire.rjw.lan) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer 0.82) id 66302f67333b10a0; Mon, 25 Sep 2017 23:19:16 +0200 From: "Rafael J. Wysocki" To: linux-pm@vger.kernel.org, Wolfram Sang Cc: linux-i2c@vger.kernel.org, linux-acpi@vger.kernel.org, Kevin Hilman , Jarkko Nikula , Andy Shevchenko , Mika Westerberg , Jisheng Zhang , John Stultz , Guodong Xu , Sumit Semwal , Haojian Zhuang , Johannes Stezenbach , Ulf Hansson , Lee Jones , Rajat Jain Subject: [Update][PATCH v5 1/3] PM: i2c-designware-platdrv: Clean up PM handling in probe Date: Mon, 25 Sep 2017 23:10:06 +0200 Message-ID: <188302021.o3ml4PkeyZ@aspire.rjw.lan> In-Reply-To: <2813826.3DA0fVXnVa@aspire.rjw.lan> References: <3023226.l5IfJK6GIc@aspire.rjw.lan> <65494652.vEfz4tCBDb@aspire.rjw.lan> <2813826.3DA0fVXnVa@aspire.rjw.lan> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Rafael J. Wysocki The power management handling in dw_i2c_plat_probe() is somewhat messy and it is rather hard to figure out the code intention for the case when pm_disabled is set. In that case, the driver doesn't enable runtime PM at all, but in addition to that it calls pm_runtime_forbid() as though it wasn't sure if runtime PM might be enabled for the device later by someone else. Although that concern doesn't seem to be actually valid, the device is clearly still expected to be PM-capable even in the pm_disabled set case, so a better approach would be to enable runtime PM for it unconditionally and prevent it from being runtime-suspended by using pm_runtime_get_noresume(). Make the driver do that. Signed-off-by: Rafael J. Wysocki --- v4 -> v5: Address the Ulf's comment that pm_runtime_forbid() was not suitable for preventing runtime suspends of the device from occurring (as it could be overridden by user space) and update the changelog. Also drop the tags as the patch changed (although that change shouldn't matter on systems where pm_disabled is not set). v3 -> v4: Added Tested-by tags. -> v3: Small update of the changelog. --- drivers/i2c/busses/i2c-designware-platdrv.c | 34 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c =================================================================== --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c @@ -249,6 +249,14 @@ static void dw_i2c_set_fifo_size(struct } } +static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev) +{ + pm_runtime_disable(dev->dev); + + if (dev->pm_disabled) + pm_runtime_put_noidle(dev->dev); +} + static int dw_i2c_plat_probe(struct platform_device *pdev) { struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -362,14 +370,17 @@ static int dw_i2c_plat_probe(struct plat ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); adap->dev.of_node = pdev->dev.of_node; - if (dev->pm_disabled) { - pm_runtime_forbid(&pdev->dev); - } else { - pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + /* The code below assumes runtime PM to be disabled. */ + WARN_ON(pm_runtime_enabled(&pdev->dev)); + + pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + + if (dev->pm_disabled) + pm_runtime_get_noresume(&pdev->dev); + + pm_runtime_enable(&pdev->dev); if (dev->mode == DW_IC_SLAVE) ret = i2c_dw_probe_slave(dev); @@ -382,8 +393,7 @@ static int dw_i2c_plat_probe(struct plat return ret; exit_probe: - if (!dev->pm_disabled) - pm_runtime_disable(&pdev->dev); + dw_i2c_plat_pm_cleanup(dev); exit_reset: if (!IS_ERR_OR_NULL(dev->rst)) reset_control_assert(dev->rst); @@ -402,8 +412,8 @@ static int dw_i2c_plat_remove(struct pla pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); - if (!dev->pm_disabled) - pm_runtime_disable(&pdev->dev); + dw_i2c_plat_pm_cleanup(dev); + if (!IS_ERR_OR_NULL(dev->rst)) reset_control_assert(dev->rst);