From patchwork Wed Aug 23 14:42:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 110855 Delivered-To: patches@linaro.org Received: by 10.37.128.210 with SMTP id c18csp7031617ybm; Wed, 23 Aug 2017 07:42:30 -0700 (PDT) X-Received: by 10.46.14.25 with SMTP id 25mr1380086ljo.35.1503499350279; Wed, 23 Aug 2017 07:42:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503499350; cv=none; d=google.com; s=arc-20160816; b=u5OjK6aQznziKx44dXx89PLq2uGtmbVJECJse/VqO0CiULs/7vv6s6h+ZW/UCDJNhm GdGSYkZaALG6hLPF8QrFosgndNCBhLBVoyZXuQb1EKKpQwaPDOb8ndyrFSAkg2Wq9s5K 17p4zj3lYrjkiqE7pCN+n48QaPugH25eBPIKTv4WpJSrEh6CizMEayPJm6TnsZcGfXOr g6q8zuXTSEIaSb5Ks7Ms5+f31c6BQUWPaKOdC+WEAjEWMXQvYUuwTWp6HV4Op5Ch3LiH sFjXWH7jYs3KnRCZWYHlw4xjFptvxepsrB0RNdi3jXaBKbl8EqOn8TZ1D+BFi0V5crZ5 itkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=lDIBk2NR58Z+N9ZpbXrSJrmZ7UOKAB/wzTiHNYC4zVk=; b=gEUSo/KpQfpBCoqAqWS/MSB7ZLv1HHtQ3UaTsAuftV0ELL6C+uYPxHlP3ZP8ERpOc+ kmuTl1dt2SSqvDzeBGSqSQts+AStReuOG5qN7JDYs6hrX6ORPFRb0ij0/3wY9QTZFGjd 85iH4XNzhZlHNHFYBmaABCucWvrtELeV4/VzGBuQcFGvKA7UYUpb8oq1M1kHQ+/3kUxy UdTcZoHlnNn9r1l17rHLYT3y4jVl9i0hjYPgDZnL8kao4l0lUpXWRaH/O63tgQnYFp+v s3zKtzFKt8V6NVKqllvaTyT8r+awOE0VBLBy2EhKbl1gFFRa5rsMDONpVyZZVQN8QVqX e4yA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Ai6rmE0G; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::229 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-lf0-x229.google.com (mail-lf0-x229.google.com. [2a00:1450:4010:c07::229]) by mx.google.com with ESMTPS id 3si763365ljv.298.2017.08.23.07.42.30 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Aug 2017 07:42:30 -0700 (PDT) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::229 as permitted sender) client-ip=2a00:1450:4010:c07::229; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Ai6rmE0G; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c07::229 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by mail-lf0-x229.google.com with SMTP id k186so1477415lfe.2 for ; Wed, 23 Aug 2017 07:42:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lDIBk2NR58Z+N9ZpbXrSJrmZ7UOKAB/wzTiHNYC4zVk=; b=Ai6rmE0GDUJZyyYfHdMRzCny0jgZX8/RltAQdC+ktGqJ4msDwneXh/j8w/laUg1YWf Y3Uo4ywzczswim9hVcioLIn/Z47UZpEmPtutnHElpXyINa7kVUIMD5eD102Udya28BO8 0nEvu6vc6pjKPSN4DDhHNNzU5NLcruOUc9H34= 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=lDIBk2NR58Z+N9ZpbXrSJrmZ7UOKAB/wzTiHNYC4zVk=; b=oj8vxHDXgZhykX+zbpvLjjesYdMxQqZJA2FnUHZsIt9fqKYJPkajUrAnC3jOO06MOS 2qExaxx6EzMjQJKjt875aV/yB7nlTZlaagyFJZJI+sJETvzfRULfvYZHTO03ewGhokA/ p3jhPdQpF2HSYG8Ww2ZKn3FAxmQOM8HK90EbOYgwUmmC/xjPqPzpiFblVF3QhgT782kN Opva3qS0/4QdEN0EXHNP0bKNnLcRQjH8/fA7boYTvKXJ5WKGZQvCG7BuGLb5X+QFJ3Cy 0Oi1Iv8ZLrJabhREQz9FMk95DyFhwDvweefkSNJ+RvZ9VosXjSeNtl5sUVA4DTlRw+PN +osQ== X-Gm-Message-State: AHYfb5iCeGGb/m2+lUBQYmS+KrKEwvduq23BR6ZCyzIGbDr+xxyvjP0T dlklZwLIm/45C6YDaQY= X-Received: by 10.25.17.218 with SMTP id 87mr1134207lfr.129.1503499349823; Wed, 23 Aug 2017 07:42:29 -0700 (PDT) Return-Path: Received: from localhost.localdomain (h-158-174-22-67.NA.cust.bahnhof.se. [158.174.22.67]) by smtp.gmail.com with ESMTPSA id c89sm287593lfb.78.2017.08.23.07.42.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Aug 2017 07:42:29 -0700 (PDT) From: Ulf Hansson To: Wolfram Sang , "Rafael J . Wysocki" , Len Brown , linux-acpi@vger.kernel.org, linux-pm@vger.kernel.org Cc: Kevin Hilman , Jarkko Nikula , Andy Shevchenko , Mika Westerberg , Jisheng Zhang , John Stultz , Guodong Xu , Sumit Semwal , Haojian Zhuang , linux-arm-kernel@lists.infradead.org, linux-i2c@vger.kernel.org, Ulf Hansson Subject: [PATCH v2 9/9] i2c: designware: Deploy the runtime PM centric approach for system sleep Date: Wed, 23 Aug 2017 16:42:09 +0200 Message-Id: <1503499329-28834-10-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503499329-28834-1-git-send-email-ulf.hansson@linaro.org> References: <1503499329-28834-1-git-send-email-ulf.hansson@linaro.org> Currently the device is runtime resumed in the i2c-dw-plat driver's ->suspend() callback, which is needed to manage system sleep properly. The particular reason for the runtime resume is because the PM core may unset the direct_complete flag for a parent device, in case its child device are being system suspended before. This leads to that the i2c-dw-plat driver's ->suspend() callback can be invoked when the device is runtime suspended. Runtime resuming the device in this scenario may be unnecessary, in case when the device is already in its proper lower power state for system sleep. This behaviour increases the time it takes to put the device into low power state, but means also a waste of power. Let's fix the behaviour by deploying the runtime PM centric path for system sleep, via assigning the pm_runtime_force_suspend|resume() helpers as the system sleep callbacks for the i2c-dw-plat driver. To deploy this, we must also make sure that the direct_complete path isn't used for the device. Therefore we drop the ->prepare() callback from the i2c-dw-plat driver and we inform the ACPI PM domain to not try out the direct_complete path for the device, as that is the default behaviour for the ACPI PM domain. Along with the runtime PM centric path, we also get some additional improvements of the behaviour during system sleep. More precisely: *) In case the device is/gets runtime resumed before the device_suspend() phase is entered, the PM core doesn't run the direct_complete path for the device during system sleep. During system resume, this lead to that the device will always be brought back to full power when the i2c-dw-plat driver's ->resume() callback is invoked. This may not be necessary, thus increasing the resume time for the device and wasting power. In the runtime PM centric path, the pm_runtime_force_resume() helper takes better care, as it resumes the device only in case it's really needed. Normally this means it can be postponed to be dealt with via regular calls to runtime PM (pm_runtime_get*()) instead. In other words, the device remains in its low power state until someone request a new i2c transfer, whenever that may be. **) In case the device is runtime suspended when the ->prepare() callback is invoked, the direct_complete path is tried by the PM core. If it succeeds, this leads to disabling runtime PM for the device in the device_suspend() phase. That is a problem in cases when others may need the device to be operational, as to be able send i2c transfers during the entire device_suspend() phase. By using the runtime PM centric path, we postpones runtime PM to be disabled for the device by the PM core to the regular device_suspend_late() phase. Signed-off-by: Ulf Hansson --- Changes in v2: - Rebased. - Clarify changelog. --- drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) -- 2.7.4 diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index fc6b99f..e0cbf5e 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -372,6 +372,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) if (ret) goto exit_probe; + acpi_dev_disable_direct_complete(&pdev->dev); return ret; exit_probe: @@ -387,6 +388,7 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) { struct dw_i2c_dev *dev = platform_get_drvdata(pdev); + acpi_dev_enable_direct_complete(&pdev->dev); pm_runtime_get_sync(&pdev->dev); i2c_del_adapter(&dev->adapter); @@ -413,15 +415,6 @@ static const struct of_device_id dw_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, dw_i2c_of_match); #endif -#ifdef CONFIG_PM_SLEEP -static int dw_i2c_plat_prepare(struct device *dev) -{ - return pm_runtime_suspended(dev); -} -#else -#define dw_i2c_plat_prepare NULL -#endif - #ifdef CONFIG_PM static int dw_i2c_plat_runtime_suspend(struct device *dev) { @@ -434,7 +427,7 @@ static int dw_i2c_plat_runtime_suspend(struct device *dev) return 0; } -static int dw_i2c_plat_resume(struct device *dev) +static int dw_i2c_plat_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); @@ -445,19 +438,11 @@ static int dw_i2c_plat_resume(struct device *dev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int dw_i2c_plat_suspend(struct device *dev) -{ - pm_runtime_resume(dev); - return dw_i2c_plat_runtime_suspend(dev); -} -#endif - static const struct dev_pm_ops dw_i2c_dev_pm_ops = { - .prepare = dw_i2c_plat_prepare, - SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, - dw_i2c_plat_resume, + dw_i2c_plat_runtime_resume, NULL) };