From patchwork Mon Jul 16 22:41:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: 0v3rdr0n3@gmail.com X-Patchwork-Id: 10527969 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 A3C36603ED for ; Tue, 17 Jul 2018 02:41:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9EB4928C5C for ; Tue, 17 Jul 2018 02:41:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9347328C84; Tue, 17 Jul 2018 02:41:45 +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.4 required=2.0 tests=BAYES_00, DATE_IN_PAST_03_06, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, MAILING_LIST_MULTI, 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 16E5328C5C for ; Tue, 17 Jul 2018 02:41:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730362AbeGQDL6 (ORCPT ); Mon, 16 Jul 2018 23:11:58 -0400 Received: from mail-it0-f67.google.com ([209.85.214.67]:52119 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730267AbeGQDL6 (ORCPT ); Mon, 16 Jul 2018 23:11:58 -0400 Received: by mail-it0-f67.google.com with SMTP id h2-v6so22031673itj.1; Mon, 16 Jul 2018 19:41:41 -0700 (PDT) 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; bh=thD5j6sHT+iDtXzOgiaDXPpwap/kGEvLUI9GWOn1qgg=; b=BJtu4Z3BfEx5pAMlgASq1UgJKCqKIbPVUN2RxCD2L2F16kAprOVoP6Sc+2c0hBMCZM wUBeIMfxcJA4lmMpDUdZyNMr0T+V/o04bjDw2Bg7pgeQ2fY4ny6inPZvmYQfXY3hueTV flNxrAkgV3GIUpj2kfMNy3Qxg60jLqvMf7h50VLKcdxihJfksjy5ZTp1mTueo6KmjMSZ rR5NitmIF7dKaYBgzJjHYmYARCvvjc6Q7pl0p6snG2TWwHRi0PszsqNuoBqnvorhjOK5 9WTP8TTYjm0pxvVVsDoox9fHkQhqDSyVerj2XcaWTF+2+DGuhfJo5OT8UOEUmWzE5p+5 RnCQ== 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=thD5j6sHT+iDtXzOgiaDXPpwap/kGEvLUI9GWOn1qgg=; b=LGQTPESirfSxPpc9UVC5Q3eWzqqoFbCKGYPiUB6l1yVaK0UBXnNc0MVigB9uU1RGFj hzEwMrUa1Uoy0ZMJQMkidYhhjQlo1G/+ENkTKzSPZ7bIDn8+90q8aXTq2cze/liFckbh 10cm3IduEnm0N2ZsuMsMZqVDbBGMLP/hh2ublm22JFyQYi9kqRtO8D0ak9kzRv26vnI7 aX8ju2PRlXCM8Ofx6PbbrYIRAkV+hJUVDFSqTuRslCwmBaGb2y+IbaZKQrxzFkCj9lVj Q6EPOdyTP4cVDUKWBaKSoRPrWcw2hsVXVXFmUtdck2+Nocqrqo8GqJyl8D85miwqxwQh cXjw== X-Gm-Message-State: AOUpUlG8FOO8ORi5SchSF+JbYO1Ix64VoASdnX5rgQo0RCze5CenKP8O FjgiRY2WPHDLBu0YKe05ISyf8w== X-Google-Smtp-Source: AAOMgpdQRqNqaYU9vGR9+ur5+5/TlCeidhXuDLqQIAaTxHQZBxR1zIQt73+GKGeFKcYtBGEgxLBugg== X-Received: by 2002:a24:a004:: with SMTP id o4-v6mr90183ite.19.1531795300674; Mon, 16 Jul 2018 19:41:40 -0700 (PDT) Received: from pride.cinci.rr.com (cpe-74-136-84-14.kya.res.rr.com. [74.136.84.14]) by smtp.gmail.com with ESMTPSA id k21-v6sm13944itb.28.2018.07.16.19.41.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Jul 2018 19:41:40 -0700 (PDT) From: Sam Morris <0v3rdr0n3@gmail.com> To: linux-pm@vger.kernel.org, linux-ide@vger.kernel.org, rogerq@ti.com, rafael@kernel.org Cc: Samuel Morris Subject: [PATCH 2/3] ata: ahci_platform: allow disabling of hotplug to save power Date: Mon, 16 Jul 2018 22:41:02 +0000 Message-Id: <20180716224103.7912-3-0v3rdr0n3@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180716224103.7912-1-0v3rdr0n3@gmail.com> References: <20180716224103.7912-1-0v3rdr0n3@gmail.com> 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: Samuel Morris A number of resources remain powered to support hotplug. On platforms I've worked with, allowing the ahci_platform to suspend saves about 150mW. This patch allows the device to be auto suspended if the config parameter is set. Signed-off-by: Samuel Morris --- v3 changes: -Removed the global ahci_disable_hotplug config switch in favor of just using sysfs to change runtime behavior per device. v2 changes: -Added missing CONFIG_PM_SLEEP ifdefs --- drivers/ata/ahci_platform.c | 11 ++++- drivers/ata/libahci_platform.c | 82 +++++++++++++++++++++++++++------- include/linux/ahci_platform.h | 2 + 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 99f9a895a459..757729376eda 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -68,8 +68,13 @@ static int ahci_probe(struct platform_device *pdev) return rc; } -static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, - ahci_platform_resume); +#ifdef CONFIG_PM_SLEEP +static const struct dev_pm_ops ahci_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ahci_platform_suspend, ahci_platform_resume) + SET_RUNTIME_PM_OPS(ahci_platform_runtime_suspend, + ahci_platform_runtime_resume, NULL) +}; +#endif static const struct of_device_id ahci_of_match[] = { { .compatible = "generic-ahci", }, @@ -98,7 +103,9 @@ static struct platform_driver ahci_driver = { .name = DRV_NAME, .of_match_table = ahci_of_match, .acpi_match_table = ahci_acpi_match, +#ifdef CONFIG_PM_SLEEP .pm = &ahci_pm_ops, +#endif }, }; module_platform_driver(ahci_driver); diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 30cc8f1a31e1..feee2e11fb33 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -257,7 +257,7 @@ static void ahci_platform_put_resources(struct device *dev, void *res) int c; if (hpriv->got_runtime_pm) { - pm_runtime_put_sync(dev); + pm_runtime_allow(dev); pm_runtime_disable(dev); } @@ -475,8 +475,10 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev) if (rc == -EPROBE_DEFER) goto err_out; } + + pm_runtime_set_active(dev); pm_runtime_enable(dev); - pm_runtime_get_sync(dev); + pm_runtime_forbid(dev); hpriv->got_runtime_pm = true; devres_remove_group(dev, NULL); @@ -705,6 +707,21 @@ int ahci_platform_resume_host(struct device *dev) } EXPORT_SYMBOL_GPL(ahci_platform_resume_host); +static int _ahci_platform_suspend(struct device *dev) +{ + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + int rc; + + rc = ahci_platform_suspend_host(dev); + if (rc) + return rc; + + ahci_platform_disable_resources(hpriv); + + return 0; +} + /** * ahci_platform_suspend - Suspend an ahci-platform device * @dev: the platform device to suspend @@ -716,20 +733,45 @@ EXPORT_SYMBOL_GPL(ahci_platform_resume_host); * 0 on success otherwise a negative error code */ int ahci_platform_suspend(struct device *dev) +{ + return _ahci_platform_suspend(dev); +} +EXPORT_SYMBOL_GPL(ahci_platform_suspend); + +/** + * ahci_platform_runtime_suspend - Runtime suspend an ahci-platform device + * @dev: the platform device to suspend + * + * This function suspends the host associated with the device, followed by + * disabling all the resources of the device. + * + * RETURNS: + * 0 on success otherwise a negative error code + */ +int ahci_platform_runtime_suspend(struct device *dev) +{ + return _ahci_platform_suspend(dev); +} +EXPORT_SYMBOL_GPL(ahci_platform_runtime_suspend); + +static int _ahci_platform_resume(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; int rc; - rc = ahci_platform_suspend_host(dev); + rc = ahci_platform_enable_resources(hpriv); if (rc) return rc; - ahci_platform_disable_resources(hpriv); + rc = ahci_platform_resume_host(dev); + if (rc) { + ahci_platform_disable_resources(hpriv); + return rc; + } return 0; } -EXPORT_SYMBOL_GPL(ahci_platform_suspend); /** * ahci_platform_resume - Resume an ahci-platform device @@ -743,31 +785,37 @@ EXPORT_SYMBOL_GPL(ahci_platform_suspend); */ int ahci_platform_resume(struct device *dev) { - struct ata_host *host = dev_get_drvdata(dev); - struct ahci_host_priv *hpriv = host->private_data; int rc; - rc = ahci_platform_enable_resources(hpriv); + rc = _ahci_platform_resume(dev); if (rc) return rc; - rc = ahci_platform_resume_host(dev); - if (rc) - goto disable_resources; - /* We resumed so update PM runtime state */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; - -disable_resources: - ahci_platform_disable_resources(hpriv); - - return rc; } EXPORT_SYMBOL_GPL(ahci_platform_resume); + +/** + * ahci_platform_runtime_resume - Runtime resume an ahci-platform device + * @dev: the platform device to resume + * + * This function enables all the resources of the device followed by + * resuming the host associated with the device. + * + * RETURNS: + * 0 on success otherwise a negative error code + */ +int ahci_platform_runtime_resume(struct device *dev) +{ + return _ahci_platform_resume(dev); +} +EXPORT_SYMBOL_GPL(ahci_platform_runtime_resume); + #endif MODULE_DESCRIPTION("AHCI SATA platform library"); diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index 1b0a17b22cd3..6396e6982103 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -42,5 +42,7 @@ int ahci_platform_suspend_host(struct device *dev); int ahci_platform_resume_host(struct device *dev); int ahci_platform_suspend(struct device *dev); int ahci_platform_resume(struct device *dev); +int ahci_platform_runtime_suspend(struct device *dev); +int ahci_platform_runtime_resume(struct device *dev); #endif /* _AHCI_PLATFORM_H */