From nobody Tue Oct 7 18:23:17 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 E87D021ABAA; Mon, 7 Jul 2025 18:18:54 +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=1751912335; cv=none; b=py+BBCiovYWOkiF0tabSPRT9u3PAlwAGuk4+sE0lXoq4EN8RehSxRr7BiytHesz5aqOgyHCz0TZqeRdTN3YxSqjFGmI21mECPrZgkETbZHRqBy4/XchiAYxr7NM55KPSglzHRXJ64itZvpe9zP7lLGl0ZFZd125Kce2O/yaHVck= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751912335; c=relaxed/simple; bh=5TKIYPnUQKbeAnvSQAVm79+gv2kW1++eF+Dk/A7iOcA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pMRHeixJzPP8jGl3tmSpGOzCLir9H6yGAKYdqcghs/lrwCdGY/ihJPNnereLy8pJe8CGfat4KORCO9d1hTK1Fxbske0rTCPELl0hHgxUNxCgkoQRRe9fo583NiA6l84Ne0pl6f1tJsiW/1YyJHpD8UI9z9Uwf/mHA39u87JX7SI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jqqGuki1; 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="jqqGuki1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8FE8AC4CEE3; Mon, 7 Jul 2025 18:18:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751912334; bh=5TKIYPnUQKbeAnvSQAVm79+gv2kW1++eF+Dk/A7iOcA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jqqGuki1FzE4S8DwVB5HjBH3os1vxlzUoVwODhOVFDKhNsyhbQYbkOKOBY1cxDf4k QM+kunvnTOLZLHlrLdn2W1Kw04sQE1Qd9VJnqznxhwDhyyfgKvlJjaht73UPqarkGL mISCe+RMpvqyY13MMKx/GQPCCX24wvIXITw4lyHN0lcvnnVTC46B5wsMbjMewW+3wL rrSd1lCjcvxZfEK7KVuafqUNrJaEJijFowMKtFeTjw8ZGygTsly8mc035gvDDMprJF nGR3UaPaeSdk5u0rCliWFxpxKLhSienNE/RP9cfQC9kf13jDXtWEwYIwfQRPODC3im e10v1v6gLO1Cw== From: Manivannan Sadhasivam Date: Mon, 07 Jul 2025 23:48:38 +0530 Subject: [PATCH RFC 1/3] 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: <20250707-pci-pwrctrl-perst-v1-1-c3c7e513e312@kernel.org> References: <20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org> In-Reply-To: <20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org> To: Bartosz Golaszewski , Bjorn Helgaas , Jingoo Han , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@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=2014; i=mani@kernel.org; h=from:subject:message-id; bh=5TKIYPnUQKbeAnvSQAVm79+gv2kW1++eF+Dk/A7iOcA=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBobA+F92C2H8qZ7ynDGaAqG/QekmUJ0w3hs/o4/ OqCziRLkP2JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaGwPhQAKCRBVnxHm/pHO 9eh2CACak0Kl10CL3Y9i9EWGibwu/QEEB/gnZ0AJog7PtoCPJVoWmV1pxtd7KOqsLreVMiX2rND +NIA5sznCT6vPr3v1UkHUddvbJKQy6rPyJUvZXe4iZhpSBpEP6hWYd1iOFfJyyIjHZUfFg7mlCU JK1ax3midwgJUDOofm66JTUOE+Ua9r1t4FJIhIHaf1fE9/2VJOkEDz11uRDFavZNmUSQqYOW4BX sz0YqKFXlAVSeq4VYgJaqouO6xF+B4hwBLbnjnV0ZEmlXMQt4Kq6elpc83vkdS8Ll1curDy47wL IRdSKHVdmyF1fm4ntvlL/R3D2obktHL9BtEHnKduqLHPjh5b X-Developer-Key: i=mani@kernel.org; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 To allow pwrctrl core to parse the generic resources such as PERST# GPIO before turning on the supplies. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Bartosz Golaszewski --- 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 18becc144913e04709783be43efe09c33ed2b502..97170c85d6f58f0812321716cb5= 7e1fd8856572f 100644 --- a/drivers/pci/pwrctrl/slot.c +++ b/drivers/pci/pwrctrl/slot.c @@ -36,6 +36,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) { @@ -55,8 +57,6 @@ static int pci_pwrctrl_slot_probe(struct platform_device = *pdev) if (ret) goto err_regulator_disable; =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 Tue Oct 7 18:23:17 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 632FA263F5D; Mon, 7 Jul 2025 18:18:58 +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=1751912339; cv=none; b=qFa4NM7TyyShfJLAWzJ9cjYWWMzZXVU7Ha5zID+RtvyzfykqeAx1tbl7B3h0l4qRDsEHxE/kJEV0GLi6oyQFdUOPcAy4sZ8qKp+kyEIaLibcwC6PN61qiv5gTDEpouvouSq9hiPX1gxez5k9t+YENlGpPcMOqm03h4m5HByvhTo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751912339; c=relaxed/simple; bh=Jc5W8YWG8wc8WHHktFwpIx1XLVRVaPHGDSbx0uJxsVE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T2dyztpxKTQOyCglyB1stqOmCU/Cycta+sowvmC+cubdFX8FoooR0KG1jOGsqP5pN+pKzGX8LU22ZTT9t5PLXb/TsyKXXprHohYgeuOL5tBtJAcUbNt70rbxptLcqQNch9wj3DXyQ85mjJmMN5RzkZNzDAGC7oKwjIH2p/ZY7rw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Jlq8eToU; 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="Jlq8eToU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12CABC4CEEF; Mon, 7 Jul 2025 18:18:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751912338; bh=Jc5W8YWG8wc8WHHktFwpIx1XLVRVaPHGDSbx0uJxsVE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Jlq8eToUmM5nvFNRalRuPLXy8Z8Rnl6x6nEZ+UrHDpP7fSDpS3ZfN+Sq68yu01Fmf gUnuQ/tjJzXHgRg8iplaFg6urZHQy2D0fFONhmnJK2C6Q1Q7vesfyC5WSx5QPZkfr/ +9yXmCyWMzNgtgrv3NsyX+fBv+eyd1xuXJF1Xkl36OecVG/yuMmDQgMyn/P1Yo4ZrI y/bHIMBr9R5sVZpvy2zeWnUxmfzsB3oMZrrgRgwipg9R4pBqaYeZ3QdeIavJiZSDYf mtJ7eObBqef/U5Wj+2eF2N0/ucag/LWZT28+lzwvXFMNqcFy957hFipWwmL/yX8tK5 Ejr5FbF2lVk2g== From: Manivannan Sadhasivam Date: Mon, 07 Jul 2025 23:48:39 +0530 Subject: [PATCH RFC 2/3] PCI/pwrctrl: Allow pwrctrl core to control PERST# GPIO if available 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: <20250707-pci-pwrctrl-perst-v1-2-c3c7e513e312@kernel.org> References: <20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org> In-Reply-To: <20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org> To: Bartosz Golaszewski , Bjorn Helgaas , Jingoo Han , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@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=5803; i=mani@kernel.org; h=from:subject:message-id; bh=Jc5W8YWG8wc8WHHktFwpIx1XLVRVaPHGDSbx0uJxsVE=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBobA+Fr1jxYYwqxN5mEPdnnWkmDD3HZwA3qS20I SlsHWfPiwmJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaGwPhQAKCRBVnxHm/pHO 9W1YB/9TSjFH6U9IRw5x9eTMmLVwyAxxNmB9wNnIoeNFtDVrxQ3nUIsTek8VmHeGjm3J61jE5+O ljmgtl9bnPdq9CQK0en3tBKJXNo57AV+Nwxyelk0JGp/8vr8nXR3gy9VxYWFQsimEOrTgl1dnSQ DIuxxuB8P2+ZoOBLp9NwUmb9QVZ+EeoukWuiVAOqLAUUs1VXPbhz5wSGFClnYWM76gnRXr6i1wD T3G+Pnn1nk2O3qXITu9CYyonFwoQZZUmi3wVNY1o2u31Z41VWsMwKw9vCTELrMLmuTXYKo8Mx9L Fc5BxvkJ9+mW/YSzGqIqXB0LSVdPD9yVjNZTYawWxW76J8wN X-Developer-Key: i=mani@kernel.org; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 PERST# is an (optional) auxiliary signal provided by the PCIe host to components for signalling 'Fundamental Reset' as per the PCIe spec r6.0, sec 6.6.1. If PERST# is available, it's state will be toggled during the component power-up and power-down scenarios as per the PCI Express Card Electromechanical Spec v4.0, sec 2.2. Historically, the PCIe controller drivers were directly controlling the PERST# signal together with the power supplies. But with the advent of the pwrctrl framework, the power supply control is now moved to the pwrctrl, but controller drivers still ended up toggling the PERST# signal. This only happens on Qcom platforms where pwrctrl framework is being used. But nevertheseless, it is wrong to toggle PERST# (especially deassert) without controlling the power supplies. So allow the pwrctrl core to control the PERST# GPIO is available. The controller drivers still need to parse them and populate the 'host_bridge->perst' GPIO descriptor array based on the available slots. Unfortunately, we cannot just move the PERST# handling from controller drivers as most of the controller drivers need to assert PERST# during the controller initialization. Signed-off-by: Manivannan Sadhasivam --- drivers/pci/pwrctrl/core.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/pci-pwrctrl.h | 2 ++ include/linux/pci.h | 2 ++ 3 files changed, 43 insertions(+) diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c index 6bdbfed584d6d79ce28ba9e384a596b065ca69a4..abdb46399a96c8281916f971329= d5460fcff3f6e 100644 --- a/drivers/pci/pwrctrl/core.c +++ b/drivers/pci/pwrctrl/core.c @@ -3,14 +3,19 @@ * Copyright (C) 2024 Linaro Ltd. */ =20 +#include #include #include +#include #include +#include #include #include #include #include =20 +#include "../pci.h" + static int pci_pwrctrl_notify(struct notifier_block *nb, unsigned long act= ion, void *data) { @@ -56,11 +61,42 @@ static void rescan_work_func(struct work_struct *work) */ void pci_pwrctrl_init(struct pci_pwrctrl *pwrctrl, struct device *dev) { + struct pci_host_bridge *host_bridge =3D to_pci_host_bridge(dev->parent); + int devfn; + pwrctrl->dev =3D dev; INIT_WORK(&pwrctrl->work, rescan_work_func); + + if (!host_bridge->perst) + return; + + devfn =3D of_pci_get_devfn(dev_of_node(dev)); + if (devfn >=3D 0 && host_bridge->perst[PCI_SLOT(devfn)]) + pwrctrl->perst =3D host_bridge->perst[PCI_SLOT(devfn)]; } EXPORT_SYMBOL_GPL(pci_pwrctrl_init); =20 +static void pci_pwrctrl_perst_deassert(struct pci_pwrctrl *pwrctrl) +{ + /* Bail out early to avoid the delay if PERST# is not available */ + if (!pwrctrl->perst) + return; + + msleep(PCIE_T_PVPERL_MS); + gpiod_set_value_cansleep(pwrctrl->perst, 0); + /* + * FIXME: The following delay is only required for downstream ports not + * supporting link speed greater than 5.0 GT/s. + */ + msleep(PCIE_RESET_CONFIG_DEVICE_WAIT_MS); +} + +static void pci_pwrctrl_perst_assert(struct pci_pwrctrl *pwrctrl) +{ + /* No need to validate desc here as gpiod APIs handle it for us */ + gpiod_set_value_cansleep(pwrctrl->perst, 1); +} + /** * pci_pwrctrl_device_set_ready() - Notify the pwrctrl subsystem that the = PCI * device is powered-up and ready to be detected. @@ -82,6 +118,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 +141,7 @@ 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-pwrctrl.h b/include/linux/pci-pwrctrl.h index 7d439b0675e91e920737287eaf1937f38e47f2ce..1ce6aec343fea1b77a146682f49= 9ece791be70dc 100644 --- a/include/linux/pci-pwrctrl.h +++ b/include/linux/pci-pwrctrl.h @@ -31,6 +31,7 @@ struct device_link; /** * struct pci_pwrctrl - PCI device power control context. * @dev: Address of the power controlling device. + * @perst: PERST# GPIO connected to the PCI device. * * An object of this type must be allocated by the PCI power control devic= e and * passed to the pwrctrl subsystem to trigger a bus rescan and setup a dev= ice @@ -38,6 +39,7 @@ struct device_link; */ struct pci_pwrctrl { struct device *dev; + struct gpio_desc *perst; =20 /* Private: don't use. */ struct notifier_block nb; diff --git a/include/linux/pci.h b/include/linux/pci.h index 05e68f35f39238f8b9ce08df97b384d1c1e89bbe..fcce106c7e2985ee1dd79bfcd24= 1f133e5599fe1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -39,6 +39,7 @@ #include #include #include +#include #include =20 #include @@ -600,6 +601,7 @@ 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); void *release_data; + struct gpio_desc **perst; unsigned int ignore_reset_delay:1; /* For entire hierarchy */ unsigned int no_ext_tags:1; /* No Extended Tags */ unsigned int no_inc_mrrs:1; /* No Increase MRRS */ --=20 2.45.2 From nobody Tue Oct 7 18:23:17 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 B4E1F263F5D; Mon, 7 Jul 2025 18:19:03 +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=1751912343; cv=none; b=BvbFBCLwdHzLqSqk8ZahH8cJuh+rNmcsd6lruswaxamUzqWRajZcTOgGS6xwZ3P09za7LNjN1C1n1mMMZkECkGvyRgNMn7+pHCkIKCgd0Fe97xc/4iuKZBpwyilCBVS03/o7k8Ft0FXyAVTFne9+/PTT+cKHkL3s1M4XJIEQPtE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751912343; c=relaxed/simple; bh=ZAX3axLXmsGPid8QjIJzF6CkgWt90mjjqRk1vUpOLFc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WHpC8kDYZbm0+bihZdlMCuVLEwT4pTvEHvOunS3nXXE0T/oBcKNWn0lQsptlIYb4FhpKTijsXaqtoaaUj0CFCY/wesvMtf5CHSfrCZb50J12VzRKMjcyMS2++j1q81Vh/0R2Xl1nApbOfYm3+UZX8CxD7wgjCFJDCx1ZlNWlfxA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tJx/f1Br; 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="tJx/f1Br" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8263CC4CEE3; Mon, 7 Jul 2025 18:18:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751912343; bh=ZAX3axLXmsGPid8QjIJzF6CkgWt90mjjqRk1vUpOLFc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tJx/f1BrTDDKUauZ/7vqBZMmuARouJyZ1DqduhDtmpCE+ZGn68uYIrl5CH+rLYY76 euC7a7UCwMnzCswEvSDgn9t8bHqlz1uMR20U77LOieSJ5GfgL04P16b1pRhTJ5CsJe PvXHz8hHQ+c7Dlrcb+1r5IaBPRLerEx/tcaSXtQoShFMkfC6FYu91x3N9DqEm5n9AT sYhgj2Npv7a1K9+0GSh/S2UauUUlS6NrLBj+F0wVbFi/GjyAdnYqNcjNCBFDox4m4l mMm4fSQUey0o3ZwhyC3sJFg3zsQzGqKYX/kVgbDBWYvuj18gY/6XLqpL/B2txUo6g2 EX0mtFBDu5qrw== From: Manivannan Sadhasivam Date: Mon, 07 Jul 2025 23:48:40 +0530 Subject: [PATCH RFC 3/3] PCI: qcom: Allow pwrctrl framework to control 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: <20250707-pci-pwrctrl-perst-v1-3-c3c7e513e312@kernel.org> References: <20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org> In-Reply-To: <20250707-pci-pwrctrl-perst-v1-0-c3c7e513e312@kernel.org> To: Bartosz Golaszewski , Bjorn Helgaas , Jingoo Han , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@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=4796; i=mani@kernel.org; h=from:subject:message-id; bh=ZAX3axLXmsGPid8QjIJzF6CkgWt90mjjqRk1vUpOLFc=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBobA+F4h5OF+pb4InqjarCEBdTUTr/zXS9VM7Lp 8OYXc9vfk6JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaGwPhQAKCRBVnxHm/pHO 9bgSCACZaTFJPy6WqUDGC0az5EHyD2Q4KbUCvklcaKwbZXpuz0pGxpsuHG0vcq3Ml5wlNOQp8xV ktiYR3J78sFHK+K1LWKPMBOx05LSY/wcjvQWj2ODAgUaotRuPekeCKsvUkX5htVjBSclKWjgFuX obY/z0kZ29le8ogG1XbfTxupq3tVqsXvxB0ykgzcc14b9acUHvLFdPlqI4ILXwJ+B0NQSJf6yqT XY7fT5nj69SyoSKRryV5C951rBlXajRtS976NYJth6abnbcUF7VPgRDRp9sjPpNBvOg/kxtTIbD rg9iigMwpDdqE3R30anVgx4vnvdui2Q0c/wQwtSm67V6XTy7 X-Developer-Key: i=mani@kernel.org; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 Since the Qcom platforms rely on pwrctrl framework to control the power supplies, allow it to control PERST# also. PERST# should be toggled during the power-on and power-off scenarios. But the controller driver still need to assert PERST# during the controller initialization. So only skip the deassert if pwrctrl usage is detected. The pwrctrl framework will deassert PERST# after turning on the supplies. The usage of pwrctrl framework is detected based on the new DT binding i.e., with the presence of PERST# and PHY properties in the Root Port node instead of the host bridge node. When the legacy binding is used, PERST# is only controlled by the controller driver since it is not reliable to detect whether pwrctrl is used or not. So the legacy platforms are untouched by this commit. Signed-off-by: Manivannan Sadhasivam --- drivers/pci/controller/dwc/pcie-designware-host.c | 1 + drivers/pci/controller/dwc/pcie-designware.h | 1 + drivers/pci/controller/dwc/pcie-qcom.c | 26 +++++++++++++++++++= +++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pc= i/controller/dwc/pcie-designware-host.c index af6c91ec7312bab6c6e5ad35b051d0f452fe7b8d..e45f53bb135a75963318666a479= eb6d9582f30eb 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -492,6 +492,7 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) return -ENOMEM; =20 pp->bridge =3D bridge; + bridge->perst =3D pp->perst; =20 ret =3D dw_pcie_host_get_resources(pp); if (ret) diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/con= troller/dwc/pcie-designware.h index 4165c49a0a5059cab92dee3c47f8024af9d840bd..7b28f76ebf6a2de8781746eba43= a8e3ad9a5cbb2 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -430,6 +430,7 @@ struct dw_pcie_rp { struct resource *msg_res; bool use_linkup_irq; struct pci_eq_presets presets; + struct gpio_desc **perst; }; =20 struct dw_pcie_ep_ops { diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controlle= r/dwc/pcie-qcom.c index 620ac7cf09472b84c37e83ee3ce40e94a1d9d878..61e1d0d6469030c549328ab4d8c= 65d5377d525e3 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -313,6 +313,11 @@ static void qcom_ep_reset_assert(struct qcom_pcie *pci= e) =20 static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) { + struct dw_pcie_rp *pp =3D &pcie->pci->pp; + + if (pp->perst) + return; + /* Ensure that PERST has been asserted for at least 100 ms */ msleep(PCIE_T_PVPERL_MS); qcom_perst_assert(pcie, false); @@ -1701,11 +1706,12 @@ 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) { + struct dw_pcie_rp *pp =3D &pcie->pci->pp; struct device *dev =3D pcie->pci->dev; struct qcom_pcie_port *port; struct gpio_desc *reset; struct phy *phy; - int ret; + int ret, devfn; =20 reset =3D devm_fwnode_gpiod_get(dev, of_fwnode_handle(node), "reset", GPIOD_OUT_HIGH, "PERST#"); @@ -1724,6 +1730,12 @@ static int qcom_pcie_parse_port(struct qcom_pcie *pc= ie, struct device_node *node if (ret) return ret; =20 + devfn =3D of_pci_get_devfn(node); + if (devfn < 0) + return -ENOENT; + + pp->perst[PCI_SLOT(devfn)] =3D reset; + port->reset =3D reset; port->phy =3D phy; INIT_LIST_HEAD(&port->list); @@ -1734,10 +1746,20 @@ static int qcom_pcie_parse_port(struct qcom_pcie *p= cie, struct device_node *node =20 static int qcom_pcie_parse_ports(struct qcom_pcie *pcie) { + struct dw_pcie_rp *pp =3D &pcie->pci->pp; struct device *dev =3D pcie->pci->dev; struct qcom_pcie_port *port, *tmp; + int child_cnt; int ret =3D -ENOENT; =20 + child_cnt =3D of_get_available_child_count(dev->of_node); + if (!child_cnt) + return ret; + + pp->perst =3D kcalloc(child_cnt, sizeof(struct gpio_desc *), GFP_KERNEL); + if (!pp->perst) + return -ENOMEM; + for_each_available_child_of_node_scoped(dev->of_node, of_port) { ret =3D qcom_pcie_parse_port(pcie, of_port); if (ret) @@ -1747,6 +1769,7 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pc= ie) return ret; =20 err_port_del: + kfree(pp->perst); list_for_each_entry_safe(port, tmp, &pcie->ports, list) list_del(&port->list); =20 @@ -1984,6 +2007,7 @@ static int qcom_pcie_probe(struct platform_device *pd= ev) dw_pcie_host_deinit(pp); err_phy_exit: qcom_pcie_phy_exit(pcie); + kfree(pp->perst); list_for_each_entry_safe(port, tmp, &pcie->ports, list) list_del(&port->list); err_pm_runtime_put: --=20 2.45.2