From nobody Mon Feb 9 13:02:03 2026 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 AA3F7C001DF for ; Thu, 13 Jul 2023 12:46:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234186AbjGMMqD (ORCPT ); Thu, 13 Jul 2023 08:46:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234797AbjGMMp6 (ORCPT ); Thu, 13 Jul 2023 08:45:58 -0400 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1BC92698; Thu, 13 Jul 2023 05:45:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689252353; x=1720788353; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VbWjooAKdAMxvMHk6ia791hLWwyb/8RqjapPxtyf+Bo=; b=mproLPtDQElZ4J7wzYcGpvVf/qRlCHpZSCPAz9hQZO21hSBtOCmzRkIw cyKXt3hhvrdhSSbCXc0WY1aIVw+YZhcmIszdPjy1G2FwP+2a4L3vwWyiE vAM62uTp5rmdS6lhzIpuFqikXUZnUwfTV9EfeF4WOZdCuf36aVXNimwTK s3w3QcKcCz8R+aRurWzF3VVlGPUkRTNNS3hMcyRr4cOlw7KwYsKeOVsg+ PimVKfP2zqQrOnWEdNGABk3NiyqT73hYIt6kly7ayDF49jbghilG1wjDn EQvAZ5UVyoZWJje7G9/ODtbexykxP9N+SJQmws4kYdJd+OdeFdq5crXv9 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10770"; a="367796851" X-IronPort-AV: E=Sophos;i="6.01,202,1684825200"; d="scan'208";a="367796851" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jul 2023 05:45:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10770"; a="757144415" X-IronPort-AV: E=Sophos;i="6.01,202,1684825200"; d="scan'208";a="757144415" Received: from ijarvine-mobl2.ger.corp.intel.com ([10.251.222.39]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jul 2023 05:45:46 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?UTF-8?q?Krzysztof=20Wilczy=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?Jonas=20Dre=C3=9Fler?= , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , stable@vger.kernel.org Subject: [PATCH v4 04/11] PCI/ASPM: Use RMW accessors for changing LNKCTL Date: Thu, 13 Jul 2023 15:44:58 +0300 Message-Id: <20230713124505.94866-5-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230713124505.94866-1-ilpo.jarvinen@linux.intel.com> References: <20230713124505.94866-1-ilpo.jarvinen@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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=C3=A4rvinen 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 3dafba0b5f41..207c247cba02 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -199,7 +199,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state = *link, int blacklist) static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) { int same_clock =3D 1; - u16 reg16, parent_reg, child_reg[8]; + u16 reg16, parent_old_ccc, child_old_ccc[8]; struct pci_dev *child, *parent =3D link->pdev; struct pci_bus *linkbus =3D parent->subordinate; /* @@ -221,6 +221,7 @@ static void pcie_aspm_configure_common_clock(struct pci= e_link_state *link) =20 /* Port might be already in common clock mode */ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + parent_old_ccc =3D reg16 & PCI_EXP_LNKCTL_CCC; if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) { bool consistent =3D true; =20 @@ -240,31 +241,27 @@ static void pcie_aspm_configure_common_clock(struct p= cie_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)] =3D reg16; - if (same_clock) - reg16 |=3D PCI_EXP_LNKCTL_CCC; - else - reg16 &=3D ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); + child_old_ccc[PCI_FUNC(child->devfn)] =3D 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); } =20 /* Configure upstream component */ - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); - parent_reg =3D reg16; - if (same_clock) - reg16 |=3D PCI_EXP_LNKCTL_CCC; - else - reg16 &=3D ~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); =20 if (pcie_retrain_link(link->pdev, true)) { =20 /* 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); } } =20 --=20 2.30.2