From nobody Fri Oct 3 08:53:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E88B2D94BB; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; cv=none; b=HKiGbDSoYgtWaztfU7TpNU1YFwd2Ie1krGsWvDky5nats5uW4TjeXUQtjYmI5GLZQnKcJ/IP56kRNBOXb2SfKvXsHTBtC+O48EVX6m4+uKHJHVqoXbBnugJNtdiemhqMdlqzB78CO8lrcIIBAe4BGM6bYzTtFyXTFb1rOThEnms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; c=relaxed/simple; bh=maiVLm37ymmwT1M55VwLwvJeZ1s/3l1kJVolnRGJHx0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=An77HWcG1FDlZ2NNW/UwteggggfM3nSCI7UIucX6epfAz+/msbmavgjCCRQAn6YoTUej9f80jFM+u6lFaaojO9MaKKp2kL4JIbxkYdLf0GW4Llx/IjtXiuHw7Ow7uI4xif2m3FieXxlVEmtZZMQa6tEN8gM8FvymF9irFgqKipQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J2lUtnxl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J2lUtnxl" Received: by smtp.kernel.org (Postfix) with ESMTPS id 94BBEC4CEF1; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756883613; bh=maiVLm37ymmwT1M55VwLwvJeZ1s/3l1kJVolnRGJHx0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=J2lUtnxlaynleS+f7Jjjduz8/w0gBNwHVk9Os6v6f0wqh6OJjJdjq9A+8W6Ux65Tu L7RF1emAXwdQGaCF03m3QYpjhhvCEbQXYZOxSHrT59J/q6c9jc4vZ7Hf8BTzisy+OV JoORkT5uHxDFrvTePmll3igCR7B+qtMlmG+IovDNrBVWxG3gujC8WrrPPWc0QIpc/C rEGKaOtGSJmy5ytwp+Ph/1J4+CULRQall7Gwv3djmRcNXpraoQ7uXZTZKo80LhtXXn 7Hn5Kq8L2iW07XqXmzqb8Umg9BJZW+SCcZumU/4FPAm1u6nLiAEesAtdk8pbUMymqH rrQe9x8Ks5aRg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81749CA100C; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 03 Sep 2025 12:43:23 +0530 Subject: [PATCH v2 1/5] PCI: qcom: Wait for PCIE_RESET_CONFIG_WAIT_MS after PERST# deassert Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250903-pci-pwrctrl-perst-v2-1-2d461ed0e061@oss.qualcomm.com> References: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> In-Reply-To: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> To: Manivannan Sadhasivam , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Bartosz Golaszewski , Saravana Kannan Cc: linux-pci@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Krishna Chaitanya Chundru , Brian Norris , Manivannan Sadhasivam , stable+noautosel@kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2070; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=9ldRJtoT9M8aIUvYrNpDc1xJbqnMXRAhHx884nJXoBk=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBot+qbui6myA5xhx7BATXkqArIl0o8QxQQnuK7Z cRMxOQwU8aJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaLfqmwAKCRBVnxHm/pHO 9VegB/9Zeph4VheLjB+IkKOTL0NC98YO8yp/4Y7o5Br7lKcS1HBWFZym4tMuSvJ+3R5h1WjAqSx sUnTb43WgIAKjNjUcnp6KwHC05keIiJ47/d/aPLZAZi4QU8X6fKCvzmWYzWrO4eRBGYRUz7dynP Q3QzgU/dB9UiFCHmY3bEDAesLv5BcgHaU7fegwZepA2r1DVv7/mc2J61H4BVy/iv6qGMYuteHFN 0z8ouEe4TqxQl+3EnK8aDerbeZ25hfem1mM177TgX1DPqVHru29t7i/uN9YLaqmhKaQWM7ggepi 8SErUATmakiKAp26iHqDdepifCgMxOf0ns1bplB2vn3rrdHK X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam PCIe spec r6.0, sec 6.6.1 mandates waiting for 100ms before deasserting PERST# if the downstream port does not support Link speeds greater than 5.0 GT/s. But in practice, this delay seem to be required irrespective of the supported link speed as it gives the endpoints enough time to initialize. Hence, add the delay by reusing the PCIE_RESET_CONFIG_WAIT_MS definition if the linkup_irq is not supported. If the linkup_irq is supported, the driver already waits for 100ms in the IRQ handler post link up. Also, remove the redundant comment for PCIE_T_PVPERL_MS. Finally, the PERST_DELAY_US sleep can be moved to PERST# assert where it should be. Cc: stable+noautosel@kernel.org # non-trivial dependency Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") Signed-off-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-qcom.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controlle= r/dwc/pcie-qcom.c index 294babe1816e4d0c2b2343fe22d89af72afcd6cd..bcd080315d70e64eafdefd85274= 0fe07df3dbe75 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -302,20 +302,22 @@ static void qcom_perst_assert(struct qcom_pcie *pcie,= bool assert) else list_for_each_entry(port, &pcie->ports, list) gpiod_set_value_cansleep(port->reset, val); - - usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); } =20 static void qcom_ep_reset_assert(struct qcom_pcie *pcie) { qcom_perst_assert(pcie, true); + usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); } =20 static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) { - /* Ensure that PERST has been asserted for at least 100 ms */ + struct dw_pcie_rp *pp =3D &pcie->pci->pp; + msleep(PCIE_T_PVPERL_MS); qcom_perst_assert(pcie, false); + if (!pp->use_linkup_irq) + msleep(PCIE_RESET_CONFIG_WAIT_MS); } =20 static int qcom_pcie_start_link(struct dw_pcie *pci) --=20 2.45.2 From nobody Fri Oct 3 08:53:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E8022D94AF; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; cv=none; b=oRZKEG/tl2O+OklJlhCu+vejD/OfiE/ZDyFjlGvRzyOpyDB2ZS6Cz7e1J8BUoELtiglHYJDeAz6hHw8QUhjn96YSe24K/tgo4XgUS3TIB0AWOeOiUKcmN5n4iRk3iSPjlyqmJR4B63JvnmK7Fs5LM4G12h0F2W4jxJNNhuuAXa8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; c=relaxed/simple; bh=w8gq1jN0KiRRbkHHXaDjSTc4CGx+3z84B6Oc0xZb3Z4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gDQwthgw+1JGi7XjoEO7tZFLNGEyuFASlmyKWB/3GP3D/3rxNBcXCFMUYEFOFh04i+EeoLs3uBYY8aYtJRthHUFHjDiXOaGaBMEFamOS28DfduM4Nnt2LzPRZA2ll2XbOFOn5laOvLv/wnt0WdrgERwrpX3v+FiLK/N1RWDqzGk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Hidk4h3w; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Hidk4h3w" Received: by smtp.kernel.org (Postfix) with ESMTPS id A80F9C4CEFA; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756883613; bh=w8gq1jN0KiRRbkHHXaDjSTc4CGx+3z84B6Oc0xZb3Z4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Hidk4h3wUwL7NN0tIlgeZSF0+SQX3Z9CsduLUGnjHVz4NBf9suV3+mQIbAGH5CYbB 89f+YsYPgnaDyVzBkYL5eVrdm9cxU8EzaHs0222zMqAldJyjJfFdCjiLZCipbP/Q5s LnkmGAP+lZmXDdItYUJDC2SNxmLTa0+NieAmvHGfPXOziesmdv1w2weJ82jBLdZ/Lc XO3vTs77qnK0GQDyot26krUMXWkkOIlKg17UCTo9dCuVNhiYThmxiB0No5LEa1VQh5 yy2qJmRUJdca3C07yxcij/j0pPqtwZkT7/Z5m6NSpN3K1DJkGQ/LOeCZgw9wyPUwXI i3G0+DRHUp7Aw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9696DCA1012; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 03 Sep 2025 12:43:24 +0530 Subject: [PATCH v2 2/5] PCI/pwrctrl: Move pci_pwrctrl_init() before turning ON the supplies Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250903-pci-pwrctrl-perst-v2-2-2d461ed0e061@oss.qualcomm.com> References: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> In-Reply-To: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> To: Manivannan Sadhasivam , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Bartosz Golaszewski , Saravana Kannan Cc: linux-pci@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Krishna Chaitanya Chundru , Brian Norris , Manivannan Sadhasivam , Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2110; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=R+1x069ihDCZtvKq09JWHM41uYbGfvNk9pQz/Px8wHE=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBot+qbO/xAACNP9KEFSGn85ypDyLWrklnda6PLW A/JAA7/dF2JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaLfqmwAKCRBVnxHm/pHO 9a/oB/9cLJ/bC8+2232mXn53qeplk4yY1tuKr3ytZ4bABj//fCdG3P3vCCRDdcK1h/cEJTaTwFe WFo8qg4ztA2dZ44hYfAsMTuBxQevynq+o3D3aCZFFBgfNka4o79kUljSLOgw8PiBmgtaCIo5KQf PkpV0pWqoLid6lJyjGzEYLUCFi5XLwBNH8/Rjhxh7nO/i6Mt0XRPFGgBwSxY7PMftEg1EWmUBo6 u3tHO73tWhyPNIn0ni6o4NW2pGXKfTl9z8a8gy5+ea4tGN4w9Jlrj0xRGI0weKG+FTvosjGtrPF fZ0uT7oIiuOiFd+9B5SYQuu7HpaRXLncvPkJDdAOj3YVrtjv X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam To allow pwrctrl core to parse the generic resources such as PERST# GPIO before turning on the supplies. Reviewed-by: Bartosz Golaszewski Signed-off-by: Manivannan Sadhasivam --- drivers/pci/pwrctrl/pci-pwrctrl-pwrseq.c | 4 ++-- drivers/pci/pwrctrl/slot.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-pwrseq.c b/drivers/pci/pwrctrl= /pci-pwrctrl-pwrseq.c index 4e664e7b8dd23f592c0392efbf6728fc5bf9093f..b65955adc7bd44030593e8c49d6= 0db0f39b03d03 100644 --- a/drivers/pci/pwrctrl/pci-pwrctrl-pwrseq.c +++ b/drivers/pci/pwrctrl/pci-pwrctrl-pwrseq.c @@ -80,6 +80,8 @@ static int pci_pwrctrl_pwrseq_probe(struct platform_devic= e *pdev) if (!data) return -ENOMEM; =20 + pci_pwrctrl_init(&data->ctx, dev); + data->pwrseq =3D devm_pwrseq_get(dev, pdata->target); if (IS_ERR(data->pwrseq)) return dev_err_probe(dev, PTR_ERR(data->pwrseq), @@ -95,8 +97,6 @@ static int pci_pwrctrl_pwrseq_probe(struct platform_devic= e *pdev) if (ret) return ret; =20 - pci_pwrctrl_init(&data->ctx, dev); - ret =3D devm_pci_pwrctrl_device_set_ready(dev, &data->ctx); if (ret) return dev_err_probe(dev, ret, diff --git a/drivers/pci/pwrctrl/slot.c b/drivers/pci/pwrctrl/slot.c index 6e138310b45b9f7e930b6814e0a24f7111d25fee..b68406a6b027e4d9f853e86d434= 0e0ab267b6126 100644 --- a/drivers/pci/pwrctrl/slot.c +++ b/drivers/pci/pwrctrl/slot.c @@ -38,6 +38,8 @@ static int pci_pwrctrl_slot_probe(struct platform_device = *pdev) if (!slot) return -ENOMEM; =20 + pci_pwrctrl_init(&slot->ctx, dev); + ret =3D of_regulator_bulk_get_all(dev, dev_of_node(dev), &slot->supplies); if (ret < 0) { @@ -63,8 +65,6 @@ static int pci_pwrctrl_slot_probe(struct platform_device = *pdev) "Failed to enable slot clock\n"); } =20 - pci_pwrctrl_init(&slot->ctx, dev); - ret =3D devm_pci_pwrctrl_device_set_ready(dev, &slot->ctx); if (ret) return dev_err_probe(dev, ret, "Failed to register pwrctrl driver\n"); --=20 2.45.2 From nobody Fri Oct 3 08:53:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E7802D94A8; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; cv=none; b=XBSPPqFWJIHGrj3nz0aV5HQ0hHTDwurK3HF879MLhoYRGzcOljLcaXIJdfhvmrcRwJJPGzRwSwQ/Dioi5WF1/uGahjdvHpR2OuZmyh/Tm0tl69ma8zHwp3AdmejlvEgVwmiIj+gnXeKg+7mIUNzoey89/kXbXZDELRmKS0WBXlM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; c=relaxed/simple; bh=W3hNvH5sZO6OphkLzRUvLtfBzQHcHDZJGE1fudwcs98=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pmNH4ggGazd0+Qm3k3zp6plqbM5zhbJmgTxZ470TVKIrzzpZD29Sc6/scuIQIz/SvoqSwz3Cmyv/qTcHA6Y1n5vuSw8mVEIhir17lYdThghUz2auQ83wqKz7AxScLq6p9zQ/5FIfskYVHUcfILPKDsXPrmh6u7zFUurXJq/LfXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lamvf7aQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lamvf7aQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id AF8D6C4CEFB; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756883613; bh=W3hNvH5sZO6OphkLzRUvLtfBzQHcHDZJGE1fudwcs98=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=lamvf7aQlZoLv+L1+Mq3e9Ng7cS6T+KRGH4T7zeI0l4bTTkvjTkTdtw861vywrOSx k4IQsXdmc5rPllQrp8Qpk3CAtPjNwPN4eEhxeEvzoFlCMtMW41VtqshBp5YGO5pede L71f0Dyk/HznJBaxIUySWaufcbI80QAWZA5N9awl1r+r6/sHneLSydnMDzryLHbgAN 4M6JXGQ+xlIHBBSLiL32XJpZoAn3f1m63TGrvYD8JCOgiQiPUHXCFDnFRrraAj6RGj YuPv83PIFeb259oksFhiJqMaiLTt4y93VBRIf5TUMwpa4/cJhJ1TDSd+2iYb1pch4B CbWCmIqL5/lnA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A65A9CA1013; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 03 Sep 2025 12:43:25 +0530 Subject: [PATCH v2 3/5] PCI/pwrctrl: Add support for toggling PERST# Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250903-pci-pwrctrl-perst-v2-3-2d461ed0e061@oss.qualcomm.com> References: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> In-Reply-To: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> To: Manivannan Sadhasivam , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Bartosz Golaszewski , Saravana Kannan Cc: linux-pci@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Krishna Chaitanya Chundru , Brian Norris , Manivannan Sadhasivam X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4210; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=3zHm5Gzo/IIXZ/G1nj/XT1Pq21XYLHP2BySYxIC/Q3Y=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBot+qbY5glF0uYf7AkMGjvaky6e5NrTN2X7/z1o OlGmSNmfN6JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaLfqmwAKCRBVnxHm/pHO 9bW5B/wNxh5qomqfQn0L2CarY6dq1Ht16cfCGZdHQ6mNZZOABgKfJh9R4qkoFDOyowWxYNKkkL3 p4hU/l51P8qQdshkv4vorXgOFH6NWPbo1Ro0yP3B9LiJYH3ViH5OtFt+s8Gx0tKmKOyOyYhWQ4L 50BThbQuyf8NRZNQmUiSuRfI24WHUAb6CDvcPIb0J7Uraios9c2VfvtGbc9P4BHOVkZ326rMrcL BEZu2MLmb7PuDvl/66TZ/7Zu+f4cD+OM6q8rMYiSUY0P0l1segBjMyBrDXaG9GRzaCroyNnnnpU oWr4Zuo6UVHaszOi/nxt3bhnA1xzcMlY26krJWH6dp3qvYlq X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam As per PCIe spec r6.0, sec 6.6.1, PERST# is an auxiliary signal provided by the system to a component as a Fundamental Reset. This signal if available, should conform to the rules defined by the electromechanical form factor specifications like PCIe CEM spec r4.0, sec 2.2. Since pwrctrl driver is meant to control the power supplies, it should also control the PERST# signal if available. But traditionally, the host bridge (controller) drivers are the ones parsing and controlling the PERST# signal. They also sometimes need to assert PERST# during their own hardware initialization. So it is not possible to move the PERST# control away from the controller drivers and it must be shared logically. Hence, add a new callback 'pci_host_bridge::toggle_perst', that allows the pwrctrl core to toggle PERST# with the help of the controller drivers. But care must be taken care by the controller drivers to not deassert the PERST# signal if this callback is populated. This callback if available, will be called by the pwrctrl core during the device power up and power down scenarios. Controller drivers should identify the device using the 'struct device_node' passed during the callback and toggle PERST# accordingly. Signed-off-by: Manivannan Sadhasivam --- drivers/pci/pwrctrl/core.c | 27 +++++++++++++++++++++++++++ include/linux/pci.h | 3 +++ 2 files changed, 30 insertions(+) diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c index 6bdbfed584d6d79ce28ba9e384a596b065ca69a4..8a26f432436d064acb7ebbbc9ce= 8fc339909fbe9 100644 --- a/drivers/pci/pwrctrl/core.c +++ b/drivers/pci/pwrctrl/core.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,28 @@ void pci_pwrctrl_init(struct pci_pwrctrl *pwrctrl, struc= t device *dev) } EXPORT_SYMBOL_GPL(pci_pwrctrl_init); =20 +static void pci_pwrctrl_perst_deassert(struct pci_pwrctrl *pwrctrl) +{ + struct pci_host_bridge *host_bridge =3D to_pci_host_bridge(pwrctrl->dev->= parent); + struct device_node *np =3D dev_of_node(pwrctrl->dev); + + if (!host_bridge->toggle_perst) + return; + + host_bridge->toggle_perst(host_bridge, np, false); +} + +static void pci_pwrctrl_perst_assert(struct pci_pwrctrl *pwrctrl) +{ + struct pci_host_bridge *host_bridge =3D to_pci_host_bridge(pwrctrl->dev->= parent); + struct device_node *np =3D dev_of_node(pwrctrl->dev); + + if (!host_bridge->toggle_perst) + return; + + host_bridge->toggle_perst(host_bridge, np, true); +} + /** * pci_pwrctrl_device_set_ready() - Notify the pwrctrl subsystem that the = PCI * device is powered-up and ready to be detected. @@ -82,6 +105,8 @@ int pci_pwrctrl_device_set_ready(struct pci_pwrctrl *pwr= ctrl) if (!pwrctrl->dev) return -ENODEV; =20 + pci_pwrctrl_perst_deassert(pwrctrl); + pwrctrl->nb.notifier_call =3D pci_pwrctrl_notify; ret =3D bus_register_notifier(&pci_bus_type, &pwrctrl->nb); if (ret) @@ -103,6 +128,8 @@ void pci_pwrctrl_device_unset_ready(struct pci_pwrctrl = *pwrctrl) { cancel_work_sync(&pwrctrl->work); =20 + pci_pwrctrl_perst_assert(pwrctrl); + /* * We don't have to delete the link here. Typically, this function * is only called when the power control device is being detached. If diff --git a/include/linux/pci.h b/include/linux/pci.h index 59876de13860dbe50ee6c207cd57e54f51a11079..3da62e37dba5993b52413f16ec4= 01ba3fb970a55 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -605,6 +605,9 @@ struct pci_host_bridge { void (*release_fn)(struct pci_host_bridge *); int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *de= v); +#if IS_ENABLED(CONFIG_PCI_PWRCTRL) + void (*toggle_perst)(struct pci_host_bridge *bridge, struct device_node *= np, bool assert); +#endif void *release_data; unsigned int ignore_reset_delay:1; /* For entire hierarchy */ unsigned int no_ext_tags:1; /* No Extended Tags */ --=20 2.45.2 From nobody Fri Oct 3 08:53:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E7112D8DC2; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; cv=none; b=b/EHA0/lR0wj9W0MOJWmtM646deGGhqjqe25SSo9tP1C16xrwts3MVXFMycRKmsYJrDAfD1pzzRGIH2hm8DwlacyDsEVLlhL7vUFBMdHerUvmfRPGwKD1hXhWugIbW08lIhD3UIDf48ExHM3U+ad4ZuNfiCZmpM7JyHH4tlKHnE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; c=relaxed/simple; bh=ryRtSUjZbTvYBcAKAbXA9dsM0lcTwtnSo+zNNpcuk7c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ju+fTBRex6ZTNQN94UIxGHzXTNbB4kGvKr497IXXUk/eMIAiR4CcGc6dXUxhX+Y1kAzvTPFN1xxzJWFxLKLfvxGUdhwi5tKSLXwBUpwijpA6zi6AzjMuhoj+5mL+kZamIC5jRKasFg+fkhVarUSEIErdhMHDzgsI3ksSY58NYfk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AoCmYfrA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AoCmYfrA" Received: by smtp.kernel.org (Postfix) with ESMTPS id BF3D7C4CEFD; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756883613; bh=ryRtSUjZbTvYBcAKAbXA9dsM0lcTwtnSo+zNNpcuk7c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=AoCmYfrA5mHcGW3AynQiznoVuGeMjpOd0qomcMT9ARPph7tmP4KzaaVQATjFjZPMl UgJTCvllvCO7+B6znFmRDCFAsqCtV9ldOIlMtZ0rJWTa9cJB0CYJj+A1JpNjNXMTen MjCTSk1E4YlgF7ZYjJQfvkde1NaKoPKnxwUWIvKaTJA2rzwexA3bTLBG4hh5StdfVx /UqLE37Ss1iSyoQLUl3SWiMfbFYgdnn+4UcpiXoAYEYTy1i1NtqfbTATyBe9JMycNa tcyqk2AmUFYyy5fLZTTuHQAJ1rxwiLljXFfzol10dBD91obPNogXYiiAul7pXndhkL BgdOzB//+0N1Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7900CA100C; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 03 Sep 2025 12:43:26 +0530 Subject: [PATCH v2 4/5] PCI: qcom: Parse PERST# from all PCIe bridge nodes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250903-pci-pwrctrl-perst-v2-4-2d461ed0e061@oss.qualcomm.com> References: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> In-Reply-To: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> To: Manivannan Sadhasivam , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Bartosz Golaszewski , Saravana Kannan Cc: linux-pci@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Krishna Chaitanya Chundru , Brian Norris , Manivannan Sadhasivam X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7146; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=7C92JPcjtkyNOs7TgJky3UafrbHkSLG9ZHW4enf6l14=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBot+qbIM1j3nEbr74l9EOMdPDEtz+Ft4cZWWimL DletiDdmFuJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaLfqmwAKCRBVnxHm/pHO 9UsiB/9krTVWCBwfjHxNEkg4dSJ+Bp14Dec2iEemD9P6L1W4nMsZeIk/8vSRmjoyoERKvs+r8ng 4uHCRj/VYqvlyLldyamM4OGSyxI2asAOcKAMtHSZcDMKz3JB0SRihsUbohg32cLzBBBF8bIwag4 qGH+niU/LNuMH8/4dHjwq/O91n90xZ8suM9ks+aCTsxT/rZgLwtZUh+flkD7oODC83gDhutU96z CEoPWTiwxcK2261FHGsIHVHLhqcLT+ai9Tq7OtW6Gzae+mhyZCB3LUuIwoygghbgpWdP02w3TAG dz4t/NmAE7sP5gJqU0Yds3JyGH3RM5x0CIrUsXEOHW9kXOhK X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam Devicetree schema allows the PERST# GPIO to be present in all PCIe bridge nodes, not just in Root Port node. But the current logic parses PERST# only from the Root Port node. Though it is not causing any issue on the current platforms, the upcoming platforms will have PERST# in PCIe switch downstream ports also. So this requires parsing all the PCIe bridge nodes for the PERST# GPIO. Hence, rework the parsing logic to extend to all PCIe bridge nodes starting from Root Port node. If the 'reset-gpios' property is found for a node, the GPIO descriptor will be stored in a list. It should be noted that if more than one bridge node has the same GPIO for PERST# (shared PERST#), the driver will error out. This is due to the limitation in the GPIOLIB subsystem that allows only exclusive (non-shared) access to GPIOs from consumers. But this is soon going to get fixed. Once that happens, it will get incorporated in this driver. So for now, PERST# sharing is not supported. Signed-off-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-qcom.c | 95 +++++++++++++++++++++++++++---= ---- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controlle= r/dwc/pcie-qcom.c index bcd080315d70e64eafdefd852740fe07df3dbe75..78355d12f10d263a0bb052e24c1= e2d5e8f68603d 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -273,6 +273,11 @@ struct qcom_pcie_port { struct phy *phy; }; =20 +struct qcom_pcie_perst { + struct list_head list; + struct gpio_desc *desc; +}; + struct qcom_pcie { struct dw_pcie *pci; void __iomem *parf; /* DT parf */ @@ -286,6 +291,7 @@ struct qcom_pcie { const struct qcom_pcie_cfg *cfg; struct dentry *debugfs; struct list_head ports; + struct list_head perst; bool suspended; bool use_pm_opp; }; @@ -294,14 +300,14 @@ struct qcom_pcie { =20 static void qcom_perst_assert(struct qcom_pcie *pcie, bool assert) { - struct qcom_pcie_port *port; + struct qcom_pcie_perst *perst; int val =3D assert ? 1 : 0; =20 - if (list_empty(&pcie->ports)) + if (list_empty(&pcie->perst)) gpiod_set_value_cansleep(pcie->reset, val); - else - list_for_each_entry(port, &pcie->ports, list) - gpiod_set_value_cansleep(port->reset, val); + + list_for_each_entry(perst, &pcie->perst, list) + gpiod_set_value_cansleep(perst->desc, val); } =20 static void qcom_ep_reset_assert(struct qcom_pcie *pcie) @@ -1702,20 +1708,58 @@ static const struct pci_ecam_ops pci_qcom_ecam_ops = =3D { } }; =20 -static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node= *node) +/* Parse PERST# from all nodes in depth first manner starting from @np */ +static int qcom_pcie_parse_perst(struct qcom_pcie *pcie, + struct device_node *np) { struct device *dev =3D pcie->pci->dev; - struct qcom_pcie_port *port; + struct qcom_pcie_perst *perst; struct gpio_desc *reset; - struct phy *phy; int ret; =20 - reset =3D devm_fwnode_gpiod_get(dev, of_fwnode_handle(node), - "reset", GPIOD_OUT_HIGH, "PERST#"); - if (IS_ERR(reset)) + if (!of_find_property(np, "reset-gpios", NULL)) + goto parse_child_node; + + reset =3D devm_fwnode_gpiod_get(dev, of_fwnode_handle(np), "reset", + GPIOD_OUT_HIGH, "PERST#"); + if (IS_ERR(reset)) { + /* + * FIXME: GPIOLIB currently supports exclusive GPIO access only. + * Non exclusive access is broken. But shared PERST# requires + * non-exclusive access. So once GPIOLIB properly supports it, + * implement it here. + */ + if (PTR_ERR(reset) =3D=3D -EBUSY) + dev_err(dev, "Shared PERST# is not supported\n"); + return PTR_ERR(reset); + } + + perst =3D devm_kzalloc(dev, sizeof(*perst), GFP_KERNEL); + if (!perst) + return -ENOMEM; + + perst->desc =3D reset; + list_add_tail(&perst->list, &pcie->perst); =20 - phy =3D devm_of_phy_get(dev, node, NULL); +parse_child_node: + for_each_available_child_of_node_scoped(np, child) { + ret =3D qcom_pcie_parse_perst(pcie, child); + if (ret) + return ret; + } + + return 0; +} + +static int qcom_pcie_parse_port(struct qcom_pcie *pcie, struct device_node= *np) +{ + struct device *dev =3D pcie->pci->dev; + struct qcom_pcie_port *port; + struct phy *phy; + int ret; + + phy =3D devm_of_phy_get(dev, np, NULL); if (IS_ERR(phy)) return PTR_ERR(phy); =20 @@ -1727,7 +1771,10 @@ static int qcom_pcie_parse_port(struct qcom_pcie *pc= ie, struct device_node *node if (ret) return ret; =20 - port->reset =3D reset; + ret =3D qcom_pcie_parse_perst(pcie, np); + if (ret) + return ret; + port->phy =3D phy; INIT_LIST_HEAD(&port->list); list_add_tail(&port->list, &pcie->ports); @@ -1738,8 +1785,9 @@ static int qcom_pcie_parse_port(struct qcom_pcie *pci= e, struct device_node *node static int qcom_pcie_parse_ports(struct qcom_pcie *pcie) { struct device *dev =3D pcie->pci->dev; - struct qcom_pcie_port *port, *tmp; - int ret =3D -ENOENT; + struct qcom_pcie_port *port, *tmp_port; + struct qcom_pcie_perst *perst, *tmp_perst; + int ret =3D -ENODEV; =20 for_each_available_child_of_node_scoped(dev->of_node, of_port) { ret =3D qcom_pcie_parse_port(pcie, of_port); @@ -1750,8 +1798,13 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *p= cie) return ret; =20 err_port_del: - list_for_each_entry_safe(port, tmp, &pcie->ports, list) + list_for_each_entry_safe(port, tmp_port, &pcie->ports, list) { + phy_exit(port->phy); list_del(&port->list); + } + + list_for_each_entry_safe(perst, tmp_perst, &pcie->perst, list) + list_del(&perst->list); =20 return ret; } @@ -1778,9 +1831,10 @@ static int qcom_pcie_parse_legacy_binding(struct qco= m_pcie *pcie) =20 static int qcom_pcie_probe(struct platform_device *pdev) { + struct qcom_pcie_perst *perst, *tmp_perst; + struct qcom_pcie_port *port, *tmp_port; const struct qcom_pcie_cfg *pcie_cfg; unsigned long max_freq =3D ULONG_MAX; - struct qcom_pcie_port *port, *tmp; struct device *dev =3D &pdev->dev; struct dev_pm_opp *opp; struct qcom_pcie *pcie; @@ -1848,6 +1902,7 @@ static int qcom_pcie_probe(struct platform_device *pd= ev) } =20 INIT_LIST_HEAD(&pcie->ports); + INIT_LIST_HEAD(&pcie->perst); =20 pci->dev =3D dev; pci->ops =3D &dw_pcie_ops; @@ -1927,7 +1982,7 @@ static int qcom_pcie_probe(struct platform_device *pd= ev) =20 ret =3D qcom_pcie_parse_ports(pcie); if (ret) { - if (ret !=3D -ENOENT) { + if (ret !=3D -ENODEV) { dev_err_probe(pci->dev, ret, "Failed to parse Root Port: %d\n", ret); goto err_pm_runtime_put; @@ -1987,8 +2042,10 @@ static int qcom_pcie_probe(struct platform_device *p= dev) dw_pcie_host_deinit(pp); err_phy_exit: qcom_pcie_phy_exit(pcie); - list_for_each_entry_safe(port, tmp, &pcie->ports, list) + list_for_each_entry_safe(port, tmp_port, &pcie->ports, list) list_del(&port->list); + list_for_each_entry_safe(perst, tmp_perst, &pcie->perst, list) + list_del(&perst->list); err_pm_runtime_put: pm_runtime_put(dev); pm_runtime_disable(dev); --=20 2.45.2 From nobody Fri Oct 3 08:53:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 647DC2DAFA7; Wed, 3 Sep 2025 07:13:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; cv=none; b=cklVAN4bID6qhFNzf0wWg6gzhDPlKeQ1+ZJZNaSBF2rloAPkUa2fh4yvbkfGaa5CyprvC901rrpqHmaug82UVYJJkD/mHXTDEx8kfmnh5Io938jXr41s8sK9eChvELR4jwa/9Qdrv0591TY0yz+TEhXMTRdgUbQ9EwOjXcGxz0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756883614; c=relaxed/simple; bh=SEiEmAY+lH8Mf391yVOd+WIcOj17/HO94xc8TJDgA8U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uscwqpeYnJmah+h3j24/nBQD8OvRC4IPljPzOmkca0b2/gSYxmPKPpHz5uDP+v4QgbSdCpFdIwmbnGMrdfDES0cbnJLu+iU1PKH1V8LpUaQ01FZCdgwr5Oyv2KH7TDHiUU/pCbiJs5E9IZeCfmgQEHpEpNTzqu1klXCdjUKRPhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oGePKTdd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oGePKTdd" Received: by smtp.kernel.org (Postfix) with ESMTPS id D43FEC116C6; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756883613; bh=SEiEmAY+lH8Mf391yVOd+WIcOj17/HO94xc8TJDgA8U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=oGePKTdd9YjwGLUj4uhbLoine6v5vhIFy3485IDWy/ebzcGmcAJ0Q9UHen9QVTXps 5hmim1NuBFSCIsiUfZGcyePJZzmxnm3McGno4NcAj0P1NQYTtrVC41PNETh18IPMp7 i69hWtoYMkOs9Wdgj3S7/xVpDcUjDyDy8HRugvP9Z5PVm9tjcvLserOg0YqiXp1RD1 gBgQ7njZY7AqyF8RmpTrXoLty1Sp67uDYWaXhSChdGakLj7mr259HPpjU+V4ZxcRIS FhLhwkTiJaKqJH8yYxePApaZkdzXFln4U/GpqE5Sno4u60neUV+DBoLaMCsz4aXJ0D y/dDiaXWh3YfA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C73D4CA1011; Wed, 3 Sep 2025 07:13:33 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 03 Sep 2025 12:43:27 +0530 Subject: [PATCH v2 5/5] PCI: qcom: Allow pwrctrl core to toggle PERST# for new DT binding Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250903-pci-pwrctrl-perst-v2-5-2d461ed0e061@oss.qualcomm.com> References: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> In-Reply-To: <20250903-pci-pwrctrl-perst-v2-0-2d461ed0e061@oss.qualcomm.com> To: Manivannan Sadhasivam , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Bartosz Golaszewski , Saravana Kannan Cc: linux-pci@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Krishna Chaitanya Chundru , Brian Norris , Manivannan Sadhasivam X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6596; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=jE6WYZa4c9ydpNf35QrLmvbRouO2QM2tzBO/q32DEJQ=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBot+qbrxLuzhIzbFJu6Ak/dMgK/aqGgbOTZbDrX G5u68sXRS2JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaLfqmwAKCRBVnxHm/pHO 9ZcFB/9yBkxFGLHK5AWr+zXcKlifi+99vBPZBRrUD0HFdcJnwnEu+7SSpp1HYpDchst7DV4Mnri CiPFFkjkOiEmePyT9KK0bbj/gt+tr6k93kOqD8HK0UV9X08LkvR3F0ZvtJ3jHADCKDJSvqTaLwz YTh1x1F7yD+4ok8PFwNDIS1V3c4CdaYWqFBCG8FjdUuIkDSpgPbTd1emMZQNASkAX2n0y+G14/9 gADrQgL3xPEUp4C7a7Uo0csD867v9OIuueOLd8qB3gXYGSEqvyPYpKZr4+1gz3sk+c5xHXMQs/6 2iuSliSEzJ3oo8oLh1pOcEe4IsdxjJQUWJ8zMmW7lapCioV2 X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam If the platform is using the new DT binding, let the pwrctrl core toggle PERST# for the device. This is achieved by populating the 'pci_host_bridge::toggle_perst' callback with qcom_pcie_toggle_perst(). qcom_pcie_toggle_perst() will find the PERST# GPIO descriptor associated with the supplied 'device_node' and toggles PERST#. If PERST# is not found in the supplied node, the function will look for PERST# in the parent node as a fallback. This is needed since PERST# won't be available in the endpoint node as per the DT binding. Note that the driver still asserts PERST# during the controller initialization as it is needed as per the hardware documentation. Apart from that, the driver wouldn't touch PERST# for the new binding. Signed-off-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-qcom.c | 89 +++++++++++++++++++++++++++++-= ---- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controlle= r/dwc/pcie-qcom.c index 78355d12f10d263a0bb052e24c1e2d5e8f68603d..3c5c65d7d97cac186e1b671f80b= a7296ad226d68 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -276,6 +276,7 @@ struct qcom_pcie_port { struct qcom_pcie_perst { struct list_head list; struct gpio_desc *desc; + struct device_node *np; }; =20 struct qcom_pcie { @@ -298,11 +299,50 @@ struct qcom_pcie { =20 #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) =20 -static void qcom_perst_assert(struct qcom_pcie *pcie, bool assert) +static struct gpio_desc *qcom_find_perst(struct qcom_pcie *pcie, struct de= vice_node *np) +{ + struct qcom_pcie_perst *perst; + + list_for_each_entry(perst, &pcie->perst, list) { + if (np =3D=3D perst->np) + return perst->desc; + } + + return NULL; +} + +static void qcom_toggle_perst_per_device(struct qcom_pcie *pcie, + struct device_node *np, bool assert) +{ + int val =3D assert ? 1 : 0; + struct gpio_desc *perst; + + perst =3D qcom_find_perst(pcie, np); + if (perst) + goto toggle_perst; + + /* + * If PERST# is not available in the current node, try the parent. This + * fallback is needed if the current node belongs to an endpoint or + * switch upstream port. + */ + if (np->parent) + perst =3D qcom_find_perst(pcie, np->parent); + +toggle_perst: + /* gpiod* APIs handle NULL gpio_desc gracefully. So no need to check. */ + gpiod_set_value_cansleep(perst, val); +} + +static void qcom_perst_reset(struct qcom_pcie *pcie, struct device_node *n= p, + bool assert) { struct qcom_pcie_perst *perst; int val =3D assert ? 1 : 0; =20 + if (np) + return qcom_toggle_perst_per_device(pcie, np, assert); + if (list_empty(&pcie->perst)) gpiod_set_value_cansleep(pcie->reset, val); =20 @@ -310,22 +350,34 @@ static void qcom_perst_assert(struct qcom_pcie *pcie,= bool assert) gpiod_set_value_cansleep(perst->desc, val); } =20 -static void qcom_ep_reset_assert(struct qcom_pcie *pcie) +static void qcom_ep_reset_assert(struct qcom_pcie *pcie, struct device_nod= e *np) { - qcom_perst_assert(pcie, true); + qcom_perst_reset(pcie, np, true); usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); } =20 -static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) +static void qcom_ep_reset_deassert(struct qcom_pcie *pcie, + struct device_node *np) { struct dw_pcie_rp *pp =3D &pcie->pci->pp; =20 msleep(PCIE_T_PVPERL_MS); - qcom_perst_assert(pcie, false); + qcom_perst_reset(pcie, np, false); if (!pp->use_linkup_irq) msleep(PCIE_RESET_CONFIG_WAIT_MS); } =20 +static void qcom_pcie_toggle_perst(struct pci_host_bridge *bridge, + struct device_node *np, bool assert) +{ + struct qcom_pcie *pcie =3D dev_get_drvdata(bridge->dev.parent); + + if (assert) + qcom_ep_reset_assert(pcie, np); + else + qcom_ep_reset_deassert(pcie, np); +} + static int qcom_pcie_start_link(struct dw_pcie *pci) { struct qcom_pcie *pcie =3D to_qcom_pcie(pci); @@ -1320,7 +1372,7 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) struct qcom_pcie *pcie =3D to_qcom_pcie(pci); int ret; =20 - qcom_ep_reset_assert(pcie); + qcom_ep_reset_assert(pcie, NULL); =20 ret =3D pcie->cfg->ops->init(pcie); if (ret) @@ -1336,7 +1388,13 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) goto err_disable_phy; } =20 - qcom_ep_reset_deassert(pcie); + /* + * Only deassert PERST# for all devices here if legacy binding is used. + * For the new binding, pwrctrl driver is expected to toggle PERST# for + * individual devices. + */ + if (list_empty(&pcie->perst)) + qcom_ep_reset_deassert(pcie, NULL); =20 if (pcie->cfg->ops->config_sid) { ret =3D pcie->cfg->ops->config_sid(pcie); @@ -1344,10 +1402,12 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *p= p) goto err_assert_reset; } =20 + pci->pp.bridge->toggle_perst =3D qcom_pcie_toggle_perst; + return 0; =20 err_assert_reset: - qcom_ep_reset_assert(pcie); + qcom_ep_reset_assert(pcie, NULL); err_disable_phy: qcom_pcie_phy_power_off(pcie); err_deinit: @@ -1361,7 +1421,7 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *= pp) struct dw_pcie *pci =3D to_dw_pcie_from_pp(pp); struct qcom_pcie *pcie =3D to_qcom_pcie(pci); =20 - qcom_ep_reset_assert(pcie); + qcom_ep_reset_assert(pcie, NULL); qcom_pcie_phy_power_off(pcie); pcie->cfg->ops->deinit(pcie); } @@ -1740,6 +1800,9 @@ static int qcom_pcie_parse_perst(struct qcom_pcie *pc= ie, return -ENOMEM; =20 perst->desc =3D reset; + /* Increase the refcount to make sure 'np' is valid till it is stored */ + of_node_get(np); + perst->np =3D np; list_add_tail(&perst->list, &pcie->perst); =20 parse_child_node: @@ -1803,8 +1866,10 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *p= cie) list_del(&port->list); } =20 - list_for_each_entry_safe(perst, tmp_perst, &pcie->perst, list) + list_for_each_entry_safe(perst, tmp_perst, &pcie->perst, list) { + of_node_put(perst->np); list_del(&perst->list); + } =20 return ret; } @@ -2044,8 +2109,10 @@ static int qcom_pcie_probe(struct platform_device *p= dev) qcom_pcie_phy_exit(pcie); list_for_each_entry_safe(port, tmp_port, &pcie->ports, list) list_del(&port->list); - list_for_each_entry_safe(perst, tmp_perst, &pcie->perst, list) + list_for_each_entry_safe(perst, tmp_perst, &pcie->perst, list) { + of_node_put(perst->np); list_del(&perst->list); + } err_pm_runtime_put: pm_runtime_put(dev); pm_runtime_disable(dev); --=20 2.45.2