From patchwork Wed Aug 21 18:17:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 1151072 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-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="sE1ZITFo"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46DGBt1n02z9sBF for ; Thu, 22 Aug 2019 04:19:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728700AbfHUSTA (ORCPT ); Wed, 21 Aug 2019 14:19:00 -0400 Received: from mail-wr1-f66.google.com ([209.85.221.66]:43402 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728386AbfHUSTA (ORCPT ); Wed, 21 Aug 2019 14:19:00 -0400 Received: by mail-wr1-f66.google.com with SMTP id y8so2927635wrn.10 for ; Wed, 21 Aug 2019 11:18:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=dk/6LfmE1oX8xh4qZCF6iNA2M7CxlYcaWLLLz9LpGWU=; b=sE1ZITFoLaXnVvOf00ZCcBprI80GZcyK6+BjLcyxxOoX3OEXh+qUtA2VYbJc+Bf35f xQioq0aWHGCIAU9AWoFn3f8umoi3FcobCdFgODDqwd/8yZ9KY2MwKvQIMv3u5g5N1h9a c5v6tk3NXz5xplIixP5VdeYRcEyOX00/ZCIWEFY1Iw2xwIOCoaS+c3qaVfqTsCT8KBtD GoduqrVe2ZAXndtCkOlNY5TDGuJkmOLH0OKW6P7mtYVnjSAAcwOoKFeYN/zp6nnzwqcS jFhCzi90NsWwzH2XPTmC15dtL83zfQyMqpcQBsokjd31sHHlFEt93lPxFno1lkXGvQgf lgZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=dk/6LfmE1oX8xh4qZCF6iNA2M7CxlYcaWLLLz9LpGWU=; b=AdfGzJzU2mUY5wLTo83+tfsIKTpNoFqk+GlGs7D2D3yTD4a0wBnPddjTjCANj2ys/b xE9tW6lgWshKp6uYu4xGba4gqZyYQfsB0yjAX3W3/8ZoIZjWmA2rC2tMRw05zq9U6JTN L2Ob06TzWsXYFaluFyXD3gL0Gp/FhX/7xFoo6aIZDypcnJVQuGcDDFnuFiyVYGvvO5lj gohClgUR2jYbPrtjT0z3RSwQnIbc8XQQ69F9Bx0x/ZA8MVF0i5DU0H9JuHPx32BYCnuZ A7Cz59giDZys/v3m450OcboZ7e3abWXpJOpHylHhKMzEmny+/xFOmSmCZCMH04Z1gmmS JE/w== X-Gm-Message-State: APjAAAU0EjyQpcSWKG1+ug4XrQcF42704wBXnqIO4EqBbQe0eHJya9C6 ey59Fct7rLGVBgkA8DdaukyEKRET X-Google-Smtp-Source: APXvYqwrhZIN8S/Zy4D1JUDpmQvu42E0UJiuK0ahISA2XNMziho9gIa42/ud7ao44D9JfnsZpf2msw== X-Received: by 2002:adf:91c2:: with SMTP id 60mr44581140wri.334.1566411537593; Wed, 21 Aug 2019 11:18:57 -0700 (PDT) Received: from ?IPv6:2003:ea:8f04:7c00:3d5d:5315:9e29:1daf? (p200300EA8F047C003D5D53159E291DAF.dip0.t-ipconnect.de. [2003:ea:8f04:7c00:3d5d:5315:9e29:1daf]) by smtp.googlemail.com with ESMTPSA id g65sm1922108wma.21.2019.08.21.11.18.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Aug 2019 11:18:56 -0700 (PDT) Subject: [PATCH v2 1/3] PCI/ASPM: add L1 sub-state support to pci_disable_link_state From: Heiner Kallweit To: Frederick Lawler , Bjorn Helgaas , Greg KH , Rajat Jain Cc: "linux-pci@vger.kernel.org" References: Message-ID: Date: Wed, 21 Aug 2019 20:17:05 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Add support for disabling states L1.1 and L1.2 to pci_disable_link_state. Allow separate control of ASPM and PCI PM L1 sub-states. Signed-off-by: Heiner Kallweit --- v2: - allow separate control of ASPM and PCI PM L1 sub-states --- drivers/pci/pcie/aspm.c | 11 ++++++++++- include/linux/pci-aspm.h | 10 +++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 464f8f926..1c1b9b7d6 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1095,7 +1095,16 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) if (state & PCIE_LINK_STATE_L0S) link->aspm_disable |= ASPM_STATE_L0S; if (state & PCIE_LINK_STATE_L1) - link->aspm_disable |= ASPM_STATE_L1; + /* sub-states require L1 */ + link->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS; + if (state & PCIE_LINK_STATE_L1_1) + link->aspm_disable |= ASPM_STATE_L1_1; + if (state & PCIE_LINK_STATE_L1_2) + link->aspm_disable |= ASPM_STATE_L1_2; + if (state & PCIE_LINK_STATE_L1_1_PCIPM) + link->aspm_disable |= ASPM_STATE_L1_1_PCIPM; + if (state & PCIE_LINK_STATE_L1_2_PCIPM) + link->aspm_disable |= ASPM_STATE_L1_2_PCIPM; pcie_config_aspm_link(link, policy_to_aspm_state(link)); if (state & PCIE_LINK_STATE_CLKPM) { diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h index 67064145d..f635cbdff 100644 --- a/include/linux/pci-aspm.h +++ b/include/linux/pci-aspm.h @@ -19,9 +19,13 @@ #include -#define PCIE_LINK_STATE_L0S 1 -#define PCIE_LINK_STATE_L1 2 -#define PCIE_LINK_STATE_CLKPM 4 +#define PCIE_LINK_STATE_L0S BIT(0) +#define PCIE_LINK_STATE_L1 BIT(1) +#define PCIE_LINK_STATE_CLKPM BIT(2) +#define PCIE_LINK_STATE_L1_1 BIT(3) +#define PCIE_LINK_STATE_L1_2 BIT(4) +#define PCIE_LINK_STATE_L1_1_PCIPM BIT(5) +#define PCIE_LINK_STATE_L1_2_PCIPM BIT(6) #ifdef CONFIG_PCIEASPM int pci_disable_link_state(struct pci_dev *pdev, int state); From patchwork Wed Aug 21 18:17:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 1151073 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-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="eRN7mOfP"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46DGBt5L2bz9sDQ for ; Thu, 22 Aug 2019 04:19:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728694AbfHUSTB (ORCPT ); Wed, 21 Aug 2019 14:19:01 -0400 Received: from mail-wm1-f68.google.com ([209.85.128.68]:50335 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728679AbfHUSTB (ORCPT ); Wed, 21 Aug 2019 14:19:01 -0400 Received: by mail-wm1-f68.google.com with SMTP id v15so3088119wml.0 for ; Wed, 21 Aug 2019 11:18:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=rVtfzdrmRFBQnHI9A6IJKPt4rgOl7HXVD+rwCQXJ+08=; b=eRN7mOfPs/ZjrdqQGpfH90j/fgv0WSpIpKF9tLgiAdy2a5mQuSTwqj2HiMriNZaYVy kxlLEcnQYEaMd06uv9/E2wMNtIeiXM/ZjeskdP825hV/m1yAyJQTy4S75mqv+ytHUlaS ykFhCA40FMbKZFcBZwvPKhoAFoBdirXQc/H4eQggFpUy6SpC/Dymrdr5mE+soPpTlGwZ LkSfx8WqwpoBRwmY6f/8L8D4omeLHWQ7W4BDCXC+NkPM6CfrF1mx2Iel8FrvfVHC++C6 yUtE86f+YgzLwKeoW8DL8xTPSEVc4pw11gPHk2bJW7MA7nXv9lJ6mhYZO7YGZ0xxateL bz3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=rVtfzdrmRFBQnHI9A6IJKPt4rgOl7HXVD+rwCQXJ+08=; b=QIXlrOKCWGdFv0sUKf/Bypt3o8nCFy7vco1kcVY8Ylz9nrXQkDaeQLA4luVmE8qhN2 GDe4502Umzt+qZhQUHh593If8vmmxncz182iO2E0GY3f4UP+pSDih3b0FyZKMxgRHqcs yeskRdldpFPnj0eNbN1Fs/ptpGV0wXm8RNSiUIB7vErnvVAgbMARrbTgCB9mN/kZgGjY p5r68s3+DbN7CNcLv6ZNz5prXDHONM+Y+mw57qgpkFocH6LB02V+vjqS8hZMeP1C9T4D U+q96rja1YOS+V3Gfaowvz7A1x46IZ9iTKJVjqmDbnsiASZ3zQUJprd3/4PvbCttt3OH DFSg== X-Gm-Message-State: APjAAAVAHV+vx5EKpXBXg64EW22wYBF902Qeyt2qBAuD680NDuc++4ic iMQYK/JvOLD0ctCU97c1RRG5/SP6 X-Google-Smtp-Source: APXvYqzWb9OReeF74w2r2jgvfC38duPte83a330OAiVam894mm3QsDcB435poFjG2sIaXRzdWLGjCw== X-Received: by 2002:a05:600c:228e:: with SMTP id 14mr1558378wmf.101.1566411538865; Wed, 21 Aug 2019 11:18:58 -0700 (PDT) Received: from ?IPv6:2003:ea:8f04:7c00:3d5d:5315:9e29:1daf? (p200300EA8F047C003D5D53159E291DAF.dip0.t-ipconnect.de. [2003:ea:8f04:7c00:3d5d:5315:9e29:1daf]) by smtp.googlemail.com with ESMTPSA id b4sm1082563wma.5.2019.08.21.11.18.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Aug 2019 11:18:58 -0700 (PDT) Subject: [PATCH v2 2/3] PCI/ASPM: allow to re-enable Clock PM From: Heiner Kallweit To: Frederick Lawler , Bjorn Helgaas , Greg KH , Rajat Jain Cc: "linux-pci@vger.kernel.org" References: Message-ID: Date: Wed, 21 Aug 2019 20:17:43 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org So far Clock PM can't be re-enabled once it has been disabled with a call to pci_disable_link_state(). Reason is that clkpm_capable is reset. Change this by adding a clkpm_disable field similar to aspm_disable. Signed-off-by: Heiner Kallweit --- drivers/pci/pcie/aspm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 1c1b9b7d6..149b876c9 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -65,6 +65,7 @@ struct pcie_link_state { u32 clkpm_capable:1; /* Clock PM capable? */ u32 clkpm_enabled:1; /* Current Clock PM state */ u32 clkpm_default:1; /* Default Clock PM state by BIOS */ + u32 clkpm_disable:1; /* Clock PM disabled */ /* Exit latencies */ struct aspm_latency latency_up; /* Upstream direction exit latency */ @@ -162,8 +163,11 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) static void pcie_set_clkpm(struct pcie_link_state *link, int enable) { - /* Don't enable Clock PM if the link is not Clock PM capable */ - if (!link->clkpm_capable) + /* + * Don't enable Clock PM if the link is not Clock PM capable + * or Clock PM is disabled + */ + if (!link->clkpm_capable || link->clkpm_disable) enable = 0; /* Need nothing if the specified equals to current state */ if (link->clkpm_enabled == enable) @@ -193,7 +197,8 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) } link->clkpm_enabled = enabled; link->clkpm_default = enabled; - link->clkpm_capable = (blacklist) ? 0 : capable; + link->clkpm_capable = capable; + link->clkpm_disable = blacklist ? 1 : 0; } static bool pcie_retrain_link(struct pcie_link_state *link) @@ -1107,10 +1112,9 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) link->aspm_disable |= ASPM_STATE_L1_2_PCIPM; pcie_config_aspm_link(link, policy_to_aspm_state(link)); - if (state & PCIE_LINK_STATE_CLKPM) { - link->clkpm_capable = 0; - pcie_set_clkpm(link, 0); - } + if (state & PCIE_LINK_STATE_CLKPM) + link->clkpm_disable = 1; + pcie_set_clkpm(link, policy_to_clkpm_state(link)); mutex_unlock(&aspm_lock); if (sem) up_read(&pci_bus_sem); From patchwork Wed Aug 21 18:18:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 1151074 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-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="vaN1YJTV"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46DGBw3x57z9sBF for ; Thu, 22 Aug 2019 04:19:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728679AbfHUSTE (ORCPT ); Wed, 21 Aug 2019 14:19:04 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:34558 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728386AbfHUSTD (ORCPT ); Wed, 21 Aug 2019 14:19:03 -0400 Received: by mail-wr1-f67.google.com with SMTP id s18so2962737wrn.1 for ; Wed, 21 Aug 2019 11:19:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=AEaMdgLb8UgLqPg/3neezq3exBpbsmPDtKGbQ3DqIW4=; b=vaN1YJTVq/WPgOom7yzXF449wi1CZae+swbCT+jEvZF1PckNHdWNQmS0Fn3dHT903x iQc7oC4Ih8r/m80mawYB1SXZQgvb0MIgjfz6IgLl5FAmznuUy2vY7EperXMxq/tL4LcH 7NjV9pUoE+sU50jEnydHuKLLZO2MYI6xSjH30so4Kxlals3qqNjfoKXzZIHOSvNEW5En /a0m6KGBAJ5nFbdmvVZh4iewfQEUtTtKLugiWh1p4pzcJtHstidK1EqvlxLvzJ5eEnKE 2AIsUO7dsb/SyAtNkVcbHQAqEzGOhfkHTKs+UTd3xPfU9lShivJskT3Mv3HNUW1yKzaK 8ZGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=AEaMdgLb8UgLqPg/3neezq3exBpbsmPDtKGbQ3DqIW4=; b=MocKMa/9Z6YrneDxvQLWtX7hQuwnBRz9th8pG4qo8aVF+bZEsQRDE0lp8VIWxZVGyL qpEDX3efXvuJOPZF+WlGyrQuGDO18c8rwFBLi/sn4+JtNiflLeoFwREnMjnjFugophWB 5E1UMhBZaaT2PSFloOGVJ2FRuWR51GDk5u14+/WfMG+kB94EV3LZORTC5PjpavmvjP/Z rYQC500whjM+axzgjBd6ITwYkAYlnALdW17T/+A96DZNH7LUIkCLMEitluD3n0oJQxjo RyDPBPCQWvrsZt9zAMh3pl5amaZGEU6zJBwdRwfztttr/XEPrvmAX1wbk8xIuQmkxjam RIsQ== X-Gm-Message-State: APjAAAUhXVdnhigWgzbEJVSzYMNM2izarlxiHWLt2faQrKeP+zlI7hLs XKwM8VuAZcIVqv69fjLXm45kjGKJ X-Google-Smtp-Source: APXvYqw+SCsb0v/dU9pl0L+umSkQLAVbtvYT+OfdujNwJ1LX95Bq5sLJQNSceI/lDEf9JlsDwmJKdg== X-Received: by 2002:adf:f48d:: with SMTP id l13mr44890673wro.190.1566411540117; Wed, 21 Aug 2019 11:19:00 -0700 (PDT) Received: from ?IPv6:2003:ea:8f04:7c00:3d5d:5315:9e29:1daf? (p200300EA8F047C003D5D53159E291DAF.dip0.t-ipconnect.de. [2003:ea:8f04:7c00:3d5d:5315:9e29:1daf]) by smtp.googlemail.com with ESMTPSA id r11sm17140886wrt.84.2019.08.21.11.18.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Aug 2019 11:18:59 -0700 (PDT) Subject: [PATCH v2 3/3] PCI/ASPM: add sysfs attributes for controlling ASPM From: Heiner Kallweit To: Frederick Lawler , Bjorn Helgaas , Greg KH , Rajat Jain Cc: "linux-pci@vger.kernel.org" References: Message-ID: Date: Wed, 21 Aug 2019 20:18:41 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Background of this extension is a problem with the r8169 network driver. Several combinations of board chipsets and network chip versions have problems if ASPM is enabled, therefore we have to disable ASPM per default. However especially on notebooks ASPM can provide significant power-saving, therefore we want to give users the option to enable ASPM. With the new sysfs attributes users can control which ASPM link-states are enabled/disabled. Signed-off-by: Heiner Kallweit --- v2: - use a dedicated sysfs attribute per link state - allow separate control of ASPM and PCI PM L1 sub-states --- Documentation/ABI/testing/sysfs-bus-pci | 13 ++ drivers/pci/pci.h | 8 +- drivers/pci/pcie/aspm.c | 263 +++++++++++++++++++++++- 3 files changed, 276 insertions(+), 8 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 8bfee557e..38b565c30 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -347,3 +347,16 @@ Description: If the device has any Peer-to-Peer memory registered, this file contains a '1' if the memory has been published for use outside the driver that owns the device. + +What /sys/bus/pci/devices/.../power/aspm_l0s +What /sys/bus/pci/devices/.../power/aspm_l1 +What /sys/bus/pci/devices/.../power/aspm_l1_1 +What /sys/bus/pci/devices/.../power/aspm_l1_2 +What /sys/bus/pci/devices/.../power/aspm_l1_1_pcipm +What /sys/bus/pci/devices/.../power/aspm_l1_2_pcipm +What /sys/bus/pci/devices/.../power/aspm_clkpm +date: August 2019 +Contact: Heiner Kallweit +Description: If ASPM is supported for an endpoint, then these files + can be used to disable or enable the individual + power management states. diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 3f126f808..e51c91f38 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -525,17 +525,13 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev); void pcie_aspm_exit_link_state(struct pci_dev *pdev); void pcie_aspm_pm_state_change(struct pci_dev *pdev); void pcie_aspm_powersave_config_link(struct pci_dev *pdev); +void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); +void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } -#endif - -#ifdef CONFIG_PCIEASPM_DEBUG -void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); -void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); -#else static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { } static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) { } #endif diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 149b876c9..e7dfcd1bd 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1275,38 +1275,297 @@ static ssize_t clk_ctl_store(struct device *dev, static DEVICE_ATTR_RW(link_state); static DEVICE_ATTR_RW(clk_ctl); +#endif + +static const char power_group[] = "power"; + +static struct pcie_link_state *aspm_get_parent_link(struct pci_dev *pdev) +{ + struct pci_dev *parent = pdev->bus->self; + + if (pdev->has_secondary_link) + parent = pdev; + + return parent ? parent->link_state : NULL; +} + +static bool pcie_check_valid_aspm_endpoint(struct pci_dev *pdev) +{ + struct pcie_link_state *link; + + if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT) + return false; + + link = aspm_get_parent_link(pdev); + + return link && link->aspm_capable; +} + +static ssize_t aspm_attr_show_common(struct device *dev, + struct device_attribute *attr, + char *buf, int state) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link; + int val; + + link = aspm_get_parent_link(pdev); + if (!link) + return -EOPNOTSUPP; + + mutex_lock(&aspm_lock); + val = !!(link->aspm_enabled & state); + mutex_unlock(&aspm_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t aspm_l0s_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_L0S); +} + +static ssize_t aspm_l1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_L1); +} + +static ssize_t aspm_l1_1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_L1_1); +} + +static ssize_t aspm_l1_2_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_L1_2); +} + +static ssize_t aspm_l1_1_pcipm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_L1_1_PCIPM); +} + +static ssize_t aspm_l1_2_pcipm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_L1_2_PCIPM); +} + +static ssize_t aspm_attr_store_common(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len, int state) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link; + bool state_enable; + + if (aspm_disabled) + return -EPERM; + + link = aspm_get_parent_link(pdev); + if (!link) + return -EOPNOTSUPP; + + if (!(link->aspm_capable & state)) + return -EOPNOTSUPP; + + if (strtobool(buf, &state_enable) < 0) + return -EINVAL; + + down_read(&pci_bus_sem); + mutex_lock(&aspm_lock); + + if (state_enable) + link->aspm_disable &= ~state; + else + link->aspm_disable |= state; + + if (link->aspm_disable & ASPM_STATE_L1) + link->aspm_disable |= ASPM_STATE_L1SS; + + pcie_config_aspm_link(link, policy_to_aspm_state(link)); + + mutex_unlock(&aspm_lock); + up_read(&pci_bus_sem); + + return len; +} + +static ssize_t aspm_l0s_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return aspm_attr_store_common(dev, attr, buf, len, ASPM_STATE_L0S); +} + +static ssize_t aspm_l1_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return aspm_attr_store_common(dev, attr, buf, len, ASPM_STATE_L1); +} + +static ssize_t aspm_l1_1_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return aspm_attr_store_common(dev, attr, buf, len, ASPM_STATE_L1_1); +} + +static ssize_t aspm_l1_2_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return aspm_attr_store_common(dev, attr, buf, len, ASPM_STATE_L1_2); +} + +static ssize_t aspm_l1_1_pcipm_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return aspm_attr_store_common(dev, attr, buf, len, + ASPM_STATE_L1_1_PCIPM); +} + +static ssize_t aspm_l1_2_pcipm_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + return aspm_attr_store_common(dev, attr, buf, len, + ASPM_STATE_L1_2_PCIPM); +} + +static ssize_t aspm_clkpm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link; + int val; + + link = aspm_get_parent_link(pdev); + if (!link) + return -EOPNOTSUPP; + + mutex_lock(&aspm_lock); + val = link->clkpm_enabled; + mutex_unlock(&aspm_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static ssize_t aspm_clkpm_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link; + bool state_enable; + + if (aspm_disabled) + return -EPERM; + + link = aspm_get_parent_link(pdev); + if (!link) + return -EOPNOTSUPP; + + if (!link->clkpm_capable) + return -EOPNOTSUPP; + + if (strtobool(buf, &state_enable) < 0) + return -EINVAL; + + down_read(&pci_bus_sem); + mutex_lock(&aspm_lock); + + link->clkpm_disable = !state_enable; + pcie_set_clkpm(link, policy_to_clkpm_state(link)); + + mutex_unlock(&aspm_lock); + up_read(&pci_bus_sem); + + return len; +} + +static DEVICE_ATTR_RW(aspm_l0s); +static DEVICE_ATTR_RW(aspm_l1); +static DEVICE_ATTR_RW(aspm_l1_1); +static DEVICE_ATTR_RW(aspm_l1_2); +static DEVICE_ATTR_RW(aspm_l1_1_pcipm); +static DEVICE_ATTR_RW(aspm_l1_2_pcipm); +static DEVICE_ATTR_RW(aspm_clkpm); -static char power_group[] = "power"; void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { struct pcie_link_state *link_state = pdev->link_state; + if (pcie_check_valid_aspm_endpoint(pdev)) { + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_l0s.attr, power_group); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_l1.attr, power_group); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_1.attr, power_group); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_2.attr, power_group); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_1_pcipm.attr, power_group); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_2_pcipm.attr, power_group); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_aspm_clkpm.attr, power_group); + } + if (!link_state) return; +#ifdef CONFIG_PCIEASPM_DEBUG if (link_state->aspm_support) sysfs_add_file_to_group(&pdev->dev.kobj, &dev_attr_link_state.attr, power_group); if (link_state->clkpm_capable) sysfs_add_file_to_group(&pdev->dev.kobj, &dev_attr_clk_ctl.attr, power_group); +#endif } void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) { struct pcie_link_state *link_state = pdev->link_state; + if (pcie_check_valid_aspm_endpoint(pdev)) { + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_l0s.attr, power_group); + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_l1.attr, power_group); + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_1.attr, power_group); + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_2.attr, power_group); + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_1_pcipm.attr, power_group); + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_l1_2_pcipm.attr, power_group); + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_aspm_clkpm.attr, power_group); + } + if (!link_state) return; +#ifdef CONFIG_PCIEASPM_DEBUG if (link_state->aspm_support) sysfs_remove_file_from_group(&pdev->dev.kobj, &dev_attr_link_state.attr, power_group); if (link_state->clkpm_capable) sysfs_remove_file_from_group(&pdev->dev.kobj, &dev_attr_clk_ctl.attr, power_group); -} #endif +} static int __init pcie_aspm_disable(char *str) {