From patchwork Wed May 17 10:52:29 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: 95172 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1044684vqo; Wed, 17 May 2023 04:06:44 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5b8K5cFGA88ErO3PwH+/NhNbt8nWhoSceIPu9+lwHbPZu5axnDFt+HLkD26cNKeYD0j3Mk X-Received: by 2002:a17:902:e544:b0:1ab:19f6:ef0f with SMTP id n4-20020a170902e54400b001ab19f6ef0fmr2021788plf.33.1684321604273; Wed, 17 May 2023 04:06:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684321604; cv=none; d=google.com; s=arc-20160816; b=PbqMwwFkxpEUsfmUVxxyc4HLYUwOWloFSUEOf/ZuEMJUmKbagj+xXGz81N7Vu5rYYW KCpXLFIRL5/4t1Rb9lNy14Q5vTX+wb+M5ypK5QmFIZvKac/cn11tJS0s+LLszGbwoCEr buSOdcQD4tknEcmGfEQG9mDMzqgY4oi2r2BlQn1nKJVHlpbLlXP/vu82BpwVtX0oyn81 o855i8migfV/gU6ohwkBLbkKRAxuvcDU82CR/2M5gzmdobFMJ9YWPzQyhhoouUPQe65s 7Kl396I0IJbZ4tuRS9n98dMO4c//RB3XYuWmzxGX0uD9Ini/yXXwLm1FnE3RZsWJWMrm GqHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=GeaJW4No7WCTIvmv1HzH73NlqBPjc+H/LesKHU55J5I=; b=Wz05v9j8aHruHu015G5Qx2xkhzxdpv0banXM4vFWTigg3goS8QCHUKaWVS5vcc5PYr dyaakP04hfLp4xDEYzQropAMr/JNfwwlxDdaAywTFp0u2cTTZ8r0tfybuTjvf6eP2bKt P8DmApE1gzU93jTDo+SKW4bvHyYPvhumfMNvp/aENoUtC31F4ce8C32Qvak2wmHdvftl iREpofFmh7EKGhR+Tw9xS91Y47SS3SZw0ZIE8up3PGjh6Okan/vYJPfi0Up2oCOshlfa ukUMvjfFgCwfrNnE22kbt20rjrtvh0BUyuq1aycBfZaPa5TUMgW0x1EaLSV79P6/VItN foUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JFFJYSKa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l11-20020a170902d34b00b001a97fd670d5si15726245plk.367.2023.05.17.04.06.29; Wed, 17 May 2023 04:06:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JFFJYSKa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230211AbjEQK4b (ORCPT + 99 others); Wed, 17 May 2023 06:56:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230027AbjEQK4T (ORCPT ); Wed, 17 May 2023 06:56:19 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E5AE5B82; Wed, 17 May 2023 03:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684320953; x=1715856953; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WAfCrkS5WdESkkxMjOg3f1ha/xQHkfbiEyfrsz5cDB0=; b=JFFJYSKaMWNScDsdr3wPJB7F6GU9EisUuynFHTJ+Fw2D2EIZ45Mq4SJH stqY0y79ihpZenBPg1+rJIk1B8nw/YQ4U8jouAE5PjmyWkRYb8qg3nyAY FjpPqXEgdUWIi2uCjg5kYnHDVdS15C6mpvnIzrdLbdvy/KsiE8cPympkQ Tiwzy3LULftBpltj08w+9Oz8a5gkAEwZDgrWVbFjmtqqaeZswHbKA9bG+ 6b3r6nG1Ch0eUbzEMectoWqLknj+hQUd96nGCgyCbmjByX4C34x5D28Po /laNjEC1DtHU/v6lAcoCsnuVw3s14kEf5evIaQArSxB3uxFRvZC2f+p5N w==; X-IronPort-AV: E=McAfee;i="6600,9927,10712"; a="438071642" X-IronPort-AV: E=Sophos;i="5.99,281,1677571200"; d="scan'208";a="438071642" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 May 2023 03:53:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10712"; a="734650953" X-IronPort-AV: E=Sophos;i="5.99,281,1677571200"; d="scan'208";a="734650953" Received: from lnstern-mobl1.amr.corp.intel.com (HELO ijarvine-MOBL2.ger.corp.intel.com) ([10.251.221.185]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 May 2023 03:53:07 -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 , =?utf-8?q?Stefan_M=C3=A4tje?= , Andy Shevchenko , Jesse Barnes , Matthew Garrett , Shaohua Li , Thomas Renninger , Greg Kroah-Hartman , linux-kernel@vger.kernel.org Cc: Dean Luick , =?utf-8?q?Ilpo_J=C3=A4rvin?= =?utf-8?q?en?= , stable@vger.kernel.org Subject: [PATCH v2 3/9] PCI/ASPM: Use RMW accessors for changing LNKCTL Date: Wed, 17 May 2023 13:52:29 +0300 Message-Id: <20230517105235.29176-4-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230517105235.29176-1-ilpo.jarvinen@linux.intel.com> References: <20230517105235.29176-1-ilpo.jarvinen@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766139210806432470?= X-GMAIL-MSGID: =?utf-8?q?1766139210806432470?= 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: 4ec73791a64b ("PCI: Work around Pericom PCIe-to-PCI bridge Retrain Link erratum") Fixes: 86fa6a344209 ("PCI: Factor out pcie_retrain_link() function") 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 Cc: stable@vger.kernel.org Acked-by: Rafael J. Wysocki --- drivers/pci/pcie/aspm.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index dde1ef13d0d1..426fb0bd8e3a 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -213,7 +213,6 @@ static bool pcie_wait_for_retrain(struct pci_dev *pdev) static bool pcie_retrain_link(struct pcie_link_state *link) { struct pci_dev *parent = link->pdev; - u16 reg16; /* * Ensure the updated LNKCTL parameters are used during link @@ -224,17 +223,14 @@ static bool pcie_retrain_link(struct pcie_link_state *link) if (!pcie_wait_for_retrain(parent)) return false; - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); - reg16 |= PCI_EXP_LNKCTL_RL; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pcie_capability_set_word(parent, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_RL); if (parent->clear_retrain_link) { /* * Due to an erratum in some devices the Retrain Link bit * needs to be cleared again manually to allow the link * training to succeed. */ - reg16 &= ~PCI_EXP_LNKCTL_RL; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pcie_capability_clear_word(parent, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_RL); } return pcie_wait_for_retrain(parent); @@ -248,7 +244,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; /* @@ -270,6 +266,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; @@ -289,22 +286,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; @@ -312,9 +303,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 */