From nobody Thu Dec 18 09:26:28 2025 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 66051382D2A for ; Tue, 16 Dec 2025 12:52:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765889542; cv=none; b=W1dOhK7E98O+fnsjxfmrj3QM4pheXklLTtAOOdGn8V22j7w0tcFw9+WLtCH8+sM0fQb/wOeNbOwSYaTY8QExjgL7KdkCdVCkjFzc+AaLv/9+l/fHJt7jPUi+zQPFE/R42KqteCuBTuHEGMILeMoJPc1Xr55ZFBAoUp6AFl1B5fc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765889542; c=relaxed/simple; bh=tJ3oGSmbF0uqKIwPRkbZG//2gq/sUu33RqRKbMsLjEo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o+ztXqHdB3x3hX7YLwDuWmw1Q0c9+avuoK5WzqyVbNZ3MbY3XxFFv0+M7azRv4GabWN6P0t1F7jRc4fRFJbtRYhuNNOEIXjqm9k4zqLG0Gw94nwKe3GK6cLD6sjdQov5Jvus7iWDDuRyRYnoP4qZrgyp1WZb5/vRDsL8Pce/zPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=YUvr9Lhb; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=UMiEuLCX; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="YUvr9Lhb"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="UMiEuLCX" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5BGBOLTg3391337 for ; Tue, 16 Dec 2025 12:52:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= M9RCd35HO7B795ZOFtTVgJAEk6vZrWP6EDm6tO69gdI=; b=YUvr9Lhb8HL2/Qbn BaL28BkxTMgPHz7LIjCIXeuYr0q0XT9tMTETSUlF3qrlFwjh3BpkPs/XsxJee89G YUUMBtsqQJgFYvn/YATc0O+Yvmf5N/f3DKG/eb9h61ak27BC84Sy5oUNTCg9xqo0 n+tPMUDFUitHVk8OZi40a4hvtXXIVVgzblUU1x97XYA8a2uafBsgUnKSMgjDizkb IesbeGDBLVX2/T4ZSQJP6OV1YMTvJv+02pNlltqSCQywFsRCGE1ABBqvwzj9u8Gx J83dBimO4E4FzOuiQvZ5bfHS8OgZgWENX7LAMMr19kRgKTdP8ZBwon/GMNbPQrhu tfj7GQ== Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4b36h389rx-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 16 Dec 2025 12:52:19 +0000 (GMT) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-7b8a12f0cb4so5636400b3a.3 for ; Tue, 16 Dec 2025 04:52:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1765889539; x=1766494339; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=M9RCd35HO7B795ZOFtTVgJAEk6vZrWP6EDm6tO69gdI=; b=UMiEuLCXeXaH/1bG2yCnO/rpgvkDyfQPcFsIU7n7FxDNL1LxUcue51Sglz2c1Ngy+Q GFre1IBOReZTCLjCXTyI77aIrLfyR8mByPDg1dP6bDjtUg4pK3VpDogBffZEVWUfMsJ+ HFQD4nFeKBXrFr/zvVvRdmA0CH+C6qsm/+/ISuW7+gFFztEFErkiL1bokKpNrptktPxK jvn+0b6HYzCxd3kDINyOMAq6VKZU5yl2gI4gMUIFv8z56INrIHAzeQ+huZEFAhEOj4y2 PCcKZwQbpt04onMDsrxIx6EHvtHZ2+H+5EbIjS1BJ2WyN87/o6h2ZXbl4rUzdYDtVLT3 Q6Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765889539; x=1766494339; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=M9RCd35HO7B795ZOFtTVgJAEk6vZrWP6EDm6tO69gdI=; b=O1hmCtIgd4+cU7u4B+Yc0xQYOvj6qgru2WlLBeTTT+dFCUvYOk2F8JJ2GTvDywbfFI 0uCU9ZLAo5sUisvZjfBGuoOec7GTeVPLvZQ0KXJiqRL05m/nOnvuPTpCjEPmf1uOsnRc t2Cs5Fy1LtE/v2ZFayJpo6g3dZz137m3ObqDJaBWIusXzpp9gc3c8/E6w78C9oqMD0bk kWP1gCO8F5GkvDRk98GYC4JYdqfDhMRfinYTz98a31/Lp3z9fC2g4OAFQ+trqzEcZ8LO t5hG7N1WtB+eOZzFxbojUFWxZvofra77lkgXB+Hc2RAUhH/woEGUu3z6Isq/1sEBh458 0QuA== X-Forwarded-Encrypted: i=1; AJvYcCWJcItbkd+iwJ3Av9X5tB85vTBFaKn6TUJsJfPxy6A/0MBgFVH/iIw4fpw2x+TVhHFZAkhYv5CWGT0MkmM=@vger.kernel.org X-Gm-Message-State: AOJu0Yyt626TOmfVg5SuEXkkNOantDh+ShskvnF/aUcBxGOK2UhEckS7 wjadn8oiiagT1sxO1WSYl+xfmWfFW/neMiyrWn4lIdMHEP9eV75E5EJJfdlMf+nRnRR5oZcpsHX /NKC1wyj7ZAWBYNGP9SuElTZ8LKWScKvN6YmXLqGEqlwGltjBdIIaiHVpyxIP4Y1alGMTNcAr+A 4= X-Gm-Gg: AY/fxX4OrDZgtrjKQoLx5ZrpbeZWJugTia1k9BbdFJvF/AIl0Hs/e3W2E3gcJ3Tgi5G gczp8cYx0JbHCdworTyoNprEyUfZBgh9BUFf+mgQJHxNfEM6onmNDeZmA9isW2TIUvQYJ2+iWlg laeJiF3pbMTGeu4vEAspZNkASzlLO5NO2yoMt3OMwl+SeRE4+kggNMKA0FftDVqexesx2mtx6v0 AdddAZFejPFm9SygG+B9wctA2NtD8dG6+ftlNPf43v5w7U8Ye83PcL/pcxkeF2OXHzsRkMZqJjw Dq5HU9Uq+PBnlniiOoK03tfjL4TE+PL9HKYiXbBIwnU7R1fVYBvmI9MLjh6JMLbMyhCEOrpXSUs MsRzMsp/9TO0AWfzawnx/DDXSRJ4x00tTWzj08fQV2A== X-Received: by 2002:a05:6a00:429b:b0:7e8:43f5:bd55 with SMTP id d2e1a72fcca58-7f669c8ba28mr11528953b3a.65.1765889538577; Tue, 16 Dec 2025 04:52:18 -0800 (PST) X-Google-Smtp-Source: AGHT+IGW+M8UF2OnxF2QQLMe2t94UUedPRIEiBdPAnCYqd00GJ7WaY9ekheOQ3SyQO+OsYryx/7XvA== X-Received: by 2002:a05:6a00:429b:b0:7e8:43f5:bd55 with SMTP id d2e1a72fcca58-7f669c8ba28mr11528933b3a.65.1765889538081; Tue, 16 Dec 2025 04:52:18 -0800 (PST) Received: from [192.168.1.102] ([117.193.213.190]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7f5ab7d87e8sm13634362b3a.25.2025.12.16.04.52.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Dec 2025 04:52:17 -0800 (PST) From: Manivannan Sadhasivam Date: Tue, 16 Dec 2025 18:21:46 +0530 Subject: [PATCH v2 4/5] PCI/pwrctrl: Add APIs to power on/off the pwrctrl devices 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: <20251216-pci-pwrctrl-rework-v2-4-745a563b9be6@oss.qualcomm.com> References: <20251216-pci-pwrctrl-rework-v2-0-745a563b9be6@oss.qualcomm.com> In-Reply-To: <20251216-pci-pwrctrl-rework-v2-0-745a563b9be6@oss.qualcomm.com> To: Manivannan Sadhasivam , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Bartosz Golaszewski , Bartosz Golaszewski Cc: linux-pci@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Chen-Yu Tsai , Brian Norris , Krishna Chaitanya Chundru , Niklas Cassel , Alex Elder , Manivannan Sadhasivam , Chen-Yu Tsai , Bartosz Golaszewski X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6123; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=tJ3oGSmbF0uqKIwPRkbZG//2gq/sUu33RqRKbMsLjEo=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBpQVXoJshYDHbsyksxVQhRBCuW4SoUJYUyBpS6P Gj/UPdchMOJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaUFV6AAKCRBVnxHm/pHO 9Un7CACIz8vUMEsmPwq2dAYw/IqptY36Bc+4vC1uj12ujaHijC5HIsoTEJ+/QbyjDV1CxGcLy7N WeEOc5uEuKh8tR3Uxs3Yu9JWC9wlICZWLyLrFcU2eHjgR8SugTnajWk56xCuDsQwpw7oYPjBIOo in+lSOWmVB9EC8j+YlCpNUe4vBDNco/ruQpPNZZLaLWgt2MxdT4Cmt+bBtUsRf99DLJjUfWJvqy Pt47beVYC9dxX4YUIstC6jzu/DvvL2i9Emq4PWo5WEoskr2m/vs50QVHOR2m/fjq7x1hDSr+DBC TUYtNLUFWAL7Vz089OCFUb05cTumGn3BEw/GNaeCfxne4+iP X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE2MDEwOSBTYWx0ZWRfXzHS0zAmTfO5l fBAZi80Ca+ddPQHfi2RYVv1DWEUNoS27Hi3jTZ2JyjvXqkkDsPUQW8TPwvMRd1yE5kEjDX80fVY f19LRv62avb3vfuwfb+y9Llx2c0hCChhLenGu6Gi/2nF+UVd009Hl+OWvG5H+E78z6kjxruELTW A6/eFWql6yxoExJYfSUKsqUtgn4VMw2POKFMpmMFMLIks95CQ1yC/R3RF9LR6aVGAIL45deLSfZ COGRR/x5kg7RQFxl+Y9vji9DDyc5AR9CzqK/fpQSno6qZMv3832vJIEl2EuB9CN1Lu/BzSyEkbp TiEPIB2/QAAJ6Xp6ZalD3g61dXdjQIbO+XuzuYaOaDLL6f9bKrmrA46YSXhKSKvcl7hHXRSBtx5 zoSoVJjZgyTXGTbxXW1jEUU7LkC/7w== X-Proofpoint-GUID: Oh6A0oNkB8hu91-d6W26R8_LEwgA4tFE X-Authority-Analysis: v=2.4 cv=QeRrf8bv c=1 sm=1 tr=0 ts=69415603 cx=c_pps a=m5Vt/hrsBiPMCU0y4gIsQw==:117 a=wnJ2AIBC+6MZbTdryK78rQ==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=cm27Pg_UAAAA:8 a=KKAkSRfTAAAA:8 a=RyQsIt2LcgCPV6mEHuQA:9 a=QEXdDO2ut3YA:10 a=IoOABgeZipijB_acs4fv:22 a=cvBusfyB2V15izCimMoJ:22 X-Proofpoint-ORIG-GUID: Oh6A0oNkB8hu91-d6W26R8_LEwgA4tFE X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-12-16_02,2025-12-16_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 adultscore=0 clxscore=1015 suspectscore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512160109 To fix PCIe bridge resource allocation issues when powering PCIe switches with the pwrctrl driver, introduce APIs to explicitly power on and off all related devices simultaneously. Previously, the individual pwrctrl drivers powered on/off the PCIe devices autonomously, without any control from the controller drivers. But to enforce ordering w.r.t powering on the devices, these APIs will power on/off all the devices at the same time. The pci_pwrctrl_power_on_devices() API recursively scans the PCI child nodes, makes sure that pwrctrl drivers are bind to devices, and calls their power_on() callbacks. Similarly, pci_pwrctrl_power_off_devices() API powers off devices recursively via their power_off() callbacks. These APIs are expected to be called during the controller probe and suspend/resume time to power on/off the devices. But before calling these APIs, the pwrctrl devices should've been created beforehand using the pci_pwrctrl_{create/destroy}_devices() APIs. Co-developed-by: Krishna Chaitanya Chundru Signed-off-by: Krishna Chaitanya Chundru Tested-by: Chen-Yu Tsai Reviewed-by: Bartosz Golaszewski Signed-off-by: Manivannan Sadhasivam --- drivers/pci/pwrctrl/core.c | 121 ++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/pci-pwrctrl.h | 4 ++ 2 files changed, 125 insertions(+) diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c index 6eca54e0d540..ebe1740b7c1c 100644 --- a/drivers/pci/pwrctrl/core.c +++ b/drivers/pci/pwrctrl/core.c @@ -65,6 +65,7 @@ void pci_pwrctrl_init(struct pci_pwrctrl *pwrctrl, struct= device *dev) { pwrctrl->dev =3D dev; INIT_WORK(&pwrctrl->work, rescan_work_func); + dev_set_drvdata(dev, pwrctrl); } EXPORT_SYMBOL_GPL(pci_pwrctrl_init); =20 @@ -152,6 +153,126 @@ int devm_pci_pwrctrl_device_set_ready(struct device *= dev, } EXPORT_SYMBOL_GPL(devm_pci_pwrctrl_device_set_ready); =20 +static int __pci_pwrctrl_power_on_device(struct device *dev) +{ + struct pci_pwrctrl *pwrctrl =3D dev_get_drvdata(dev); + + if (!pwrctrl) + return 0; + + return pwrctrl->power_on(pwrctrl); +} + +/* + * Power on the devices in a depth first manner. Before powering on the de= vice, + * make sure its driver is bound. + */ +static int pci_pwrctrl_power_on_device(struct device_node *np) +{ + struct platform_device *pdev; + int ret; + + for_each_available_child_of_node_scoped(np, child) { + ret =3D pci_pwrctrl_power_on_device(child); + if (ret) + return ret; + } + + pdev =3D of_find_device_by_node(np); + if (pdev) { + if (!device_is_bound(&pdev->dev)) { + dev_dbg(&pdev->dev, "driver is not bound\n"); + ret =3D -EPROBE_DEFER; + } else { + ret =3D __pci_pwrctrl_power_on_device(&pdev->dev); + } + put_device(&pdev->dev); + + if (ret) + return ret; + } + + return 0; +} + +/** + * pci_pwrctrl_power_on_devices - Power on the pwrctrl devices + * + * @parent: Parent PCI device for which the pwrctrl devices need to be pow= ered + * on. + * + * This function recursively traverses all pwrctrl devices for the child n= odes + * of the specified PCI parent device, and powers them on in a depth first + * manner. + * + * Returns: 0 on success, negative error number on error. + */ +int pci_pwrctrl_power_on_devices(struct device *parent) +{ + struct device_node *np =3D parent->of_node; + int ret; + + for_each_available_child_of_node_scoped(np, child) { + ret =3D pci_pwrctrl_power_on_device(child); + if (ret) { + pci_pwrctrl_power_off_devices(parent); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(pci_pwrctrl_power_on_devices); + +static void __pci_pwrctrl_power_off_device(struct device *dev) +{ + struct pci_pwrctrl *pwrctrl =3D dev_get_drvdata(dev); + + if (!pwrctrl) + return; + + return pwrctrl->power_off(pwrctrl); +} + +static int pci_pwrctrl_power_off_device(struct device_node *np) +{ + struct platform_device *pdev; + + for_each_available_child_of_node_scoped(np, child) + pci_pwrctrl_power_off_device(child); + + pdev =3D of_find_device_by_node(np); + if (pdev) { + if (device_is_bound(&pdev->dev)) + __pci_pwrctrl_power_off_device(&pdev->dev); + + put_device(&pdev->dev); + } + + return 0; +} + +/** + * pci_pwrctrl_power_off_devices - Power off the pwrctrl devices + * + * @parent: Parent PCI device for which the pwrctrl devices need to be pow= ered + * off. + * + * This function recursively traverses all pwrctrl devices for the child n= odes + * of the specified PCI parent device, and powers them off in a depth first + * manner. + * + * Returns: 0 on success, negative error number on error. + */ +void pci_pwrctrl_power_off_devices(struct device *parent) +{ + struct device_node *np =3D parent->of_node; + + for_each_available_child_of_node_scoped(np, child) + pci_pwrctrl_power_off_device(child); +} +EXPORT_SYMBOL_GPL(pci_pwrctrl_power_off_devices); + static int pci_pwrctrl_create_device(struct device_node *np, struct device= *parent) { struct platform_device *pdev; diff --git a/include/linux/pci-pwrctrl.h b/include/linux/pci-pwrctrl.h index 5590ffec0bea..1b77769eebbe 100644 --- a/include/linux/pci-pwrctrl.h +++ b/include/linux/pci-pwrctrl.h @@ -57,8 +57,12 @@ int devm_pci_pwrctrl_device_set_ready(struct device *dev, #if IS_ENABLED(CONFIG_PCI_PWRCTRL) int pci_pwrctrl_create_devices(struct device *parent); void pci_pwrctrl_destroy_devices(struct device *parent); +int pci_pwrctrl_power_on_devices(struct device *parent); +void pci_pwrctrl_power_off_devices(struct device *parent); #else static inline int pci_pwrctrl_create_devices(struct device *parent) { retu= rn 0; } static void pci_pwrctrl_destroy_devices(struct device *parent) { } +static inline int pci_pwrctrl_power_on_devices(struct device *parent) { re= turn 0; } +static void pci_pwrctrl_power_off_devices(struct device *parent) { } #endif #endif /* __PCI_PWRCTRL_H__ */ --=20 2.48.1