From patchwork Tue Jun 20 13:46:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 13285896 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D930EB64D8 for ; Tue, 20 Jun 2023 13:47:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233117AbjFTNrZ (ORCPT ); Tue, 20 Jun 2023 09:47:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233122AbjFTNrM (ORCPT ); Tue, 20 Jun 2023 09:47:12 -0400 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B97B170F; Tue, 20 Jun 2023 06:47:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687268829; x=1718804829; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=d5PmbWTATtOh8RT5xNo73I1YMMCi9oeR1o9YgvVGqUY=; b=d8ChWtPWD1+6pMybKJbtbuGMZ4+vpHolRxMzEJiWuloSYp69X9UXSPAv UmENmZdRl6NEcAIeuviW3nCfGxcKDY7Hq+i3DtCbGWUk3LxY7fquooxh5 Xf96FUYZ+VybbzEJ8hAxysx4vGrgwoZsrWIL8Ydg2JC7tMAf1nJ76OzpD n97ECPebLOX8D17Iwet7FhcHUWs/Kr8QFsuQKrVXC59Hu2w3aQ2WH4K/7 chNaKtYk27faG74+bgatvVaYaf8tkODQRDBZswHZt63Zb/FxenzNSWSea HWrKJBoG5HJVVDi4T4mkoQ4qzPmZc1bQGwWvyprwhuON4HBjVOLxYGtIq Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10747"; a="362401382" X-IronPort-AV: E=Sophos;i="6.00,257,1681196400"; d="scan'208";a="362401382" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2023 06:47:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10747"; a="827006728" X-IronPort-AV: E=Sophos;i="6.00,257,1681196400"; d="scan'208";a="827006728" Received: from eshaanan-mobl.ger.corp.intel.com (HELO ijarvine-mobl2.ger.corp.intel.com) ([10.252.61.137]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2023 06:47:04 -0700 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Emmanuel Grumbach , "Rafael J . Wysocki" , Heiner Kallweit , Lukas Wunner , Jesse Barnes , Matthew Garrett , Shaohua Li , Thomas Renninger , Greg Kroah-Hartman , linux-kernel@vger.kernel.org Cc: Dean Luick , Andy Shevchenko , =?utf-8?q?Ilpo_J=C3=A4?= =?utf-8?q?rvinen?= , stable@vger.kernel.org Subject: [PATCH v3 04/10] PCI/ASPM: Use RMW accessors for changing LNKCTL Date: Tue, 20 Jun 2023 16:46:18 +0300 Message-Id: <20230620134624.99688-5-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230620134624.99688-1-ilpo.jarvinen@linux.intel.com> References: <20230620134624.99688-1-ilpo.jarvinen@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Don't assume that the device is fully under the control of ASPM and use RMW capability accessors which do proper locking to avoid losing concurrent updates to the register values. If configuration fails in pcie_aspm_configure_common_clock(), the function attempts to restore the old PCI_EXP_LNKCTL_CCC settings. Store only the old PCI_EXP_LNKCTL_CCC bit for the relevant devices rather than the content of the whole LNKCTL registers. It aligns better with how pcie_lnkctl_clear_and_set() expects its parameter and makes the code more obvious to understand. Fixes: 2a42d9dba784 ("PCIe: ASPM: Break out of endless loop waiting for PCI config bits to switch") Fixes: 7d715a6c1ae5 ("PCI: add PCI Express ASPM support") Suggested-by: Lukas Wunner Signed-off-by: Ilpo Järvinen Acked-by: Rafael J. Wysocki Cc: stable@vger.kernel.org --- drivers/pci/pcie/aspm.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 50e32bda4656..1d620e4a347d 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -228,7 +228,7 @@ static bool pcie_retrain_link(struct pcie_link_state *link) static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) { int same_clock = 1; - u16 reg16, parent_reg, child_reg[8]; + u16 reg16, parent_old_ccc, child_old_ccc[8]; struct pci_dev *child, *parent = link->pdev; struct pci_bus *linkbus = parent->subordinate; /* @@ -250,6 +250,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) /* Port might be already in common clock mode */ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + parent_old_ccc = reg16 & PCI_EXP_LNKCTL_CCC; if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) { bool consistent = true; @@ -269,22 +270,16 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) /* Configure downstream component, all functions */ list_for_each_entry(child, &linkbus->devices, bus_list) { pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); - child_reg[PCI_FUNC(child->devfn)] = reg16; - if (same_clock) - reg16 |= PCI_EXP_LNKCTL_CCC; - else - reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); + child_old_ccc[PCI_FUNC(child->devfn)] = reg16 & PCI_EXP_LNKCTL_CCC; + pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, + same_clock ? PCI_EXP_LNKCTL_CCC : 0); } /* Configure upstream component */ - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); - parent_reg = reg16; - if (same_clock) - reg16 |= PCI_EXP_LNKCTL_CCC; - else - reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, + same_clock ? PCI_EXP_LNKCTL_CCC : 0); if (pcie_retrain_link(link)) return; @@ -292,9 +287,11 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) /* Training failed. Restore common clock configurations */ pci_err(parent, "ASPM: Could not configure common clock\n"); list_for_each_entry(child, &linkbus->devices, bus_list) - pcie_capability_write_word(child, PCI_EXP_LNKCTL, - child_reg[PCI_FUNC(child->devfn)]); - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); + pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, + child_old_ccc[PCI_FUNC(child->devfn)]); + pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, parent_old_ccc); } /* Convert L0s latency encoding to ns */