From patchwork Tue Feb 4 07:34:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 13958731 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) (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 04DA2204088; Tue, 4 Feb 2025 07:35:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654517; cv=none; b=XLOgxamqlXpehijkBNd4TgIPsScpLrdos8uEOsKC/xT/UqPe4aDkONN/W+b/QnWryLUZ6y2OKOMquuOcpHjEJLbV05PxtIcTVKN1fdIynvZCi/k37GjnJRZH8L0DoDt/eINxJPSpqnLX7iR+rP2q8u/sQbq2ebslahTN78lh7SU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654517; c=relaxed/simple; bh=PHlzqRj1sngGJYA76SXKxZ8DZkGZFysxquQ/bui3h7M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Pyo+xsKrHV0fqeYgRgvcpg84/Y06qlOC/I9QpFgEs2nXNoeTTcpUdkGF8siubOVnkzcYRFpzxcObtHfXRWuRsGqJ10awisAXIn9LgHYXE6LS5oTE4PZEdcicfExBFIJSJD60v/QZ5HfYcr61+k0eYu/CkFlqXtjhSLBtjsWV08M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=JTVi+tqK; arc=none smtp.client-ip=217.70.183.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="JTVi+tqK" Received: by mail.gandi.net (Postfix) with ESMTPA id AA63D433D9; Tue, 4 Feb 2025 07:35:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1738654513; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bhuw/cTd1RZnZuhDVYg+ubS8tMPFFPrwAHU5ngfd3FU=; b=JTVi+tqKGMr5UCO/Luigw5FedhD8NaCKpjxmqsF1wsdUAUOlLyeMPolXLc9acteuGxTG9z jvS0tEJdAOxQGzgJw2NkbcZA7wFcxm3r/Be0RP7dJTq4YINWeHtjTjVxL9JNaM8t+6pujU R+Wa3INSBPBKmthKSJoBolBS0PqhVVCQeruaNRcCjxJW5rm/JDQTSR/fD5MATjjWqxdzUQ hN5nlICBetYkFRX+j4c8C1BI0HbjZoOB6JFJd4YN6Ru+3+6opyDM6ajlOrhpriAhCN21d9 7HesHQXsH+yom7vtbNxnVILzF07let1yRFpDus0qjelzTZR3Gw7uWACQQmvYBA== From: Herve Codina To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Rob Herring , Saravana Kannan , Bjorn Helgaas , Lizhi Hou Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Herve Codina Subject: [PATCH v7 1/5] driver core: Introduce device_{add,remove}_of_node() Date: Tue, 4 Feb 2025 08:34:56 +0100 Message-ID: <20250204073501.278248-2-herve.codina@bootlin.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250204073501.278248-1-herve.codina@bootlin.com> References: <20250204073501.278248-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduleelvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepjfgvrhhvvgcuvehoughinhgruceohhgvrhhvvgdrtghoughinhgrsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehffeigfejueelueeuffelueefgfelhfejhfehieegudekteeiledttdfhffekffenucfkphepvdgrtddumegvtdgrmedvgeeimeejjeeltdemvdeitgegmegvvddvmeeitdefugemheekrgenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpedvrgdtudemvgdtrgemvdegieemjeejledtmedviegtgeemvgdvvdemiedtfegumeehkegrpdhhvghloheplhhotggrlhhhohhsthdrlhhotggrlhguohhmrghinhdpmhgrihhlfhhrohhmpehhvghrvhgvrdgtohguihhnrgessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepudehpdhrtghpthhtohepghhrvghgkhhhsehlihhnuhigfhhouhhnuggrthhiohhnrdhorhhgpdhrtghpthhtoheprhgrfhgrvghlsehkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghkrheskhgvrhhnvghlrdhorhhgpdhrtghpthhtoheprhhosghhsehkvghrn hgvlhdrohhrghdprhgtphhtthhopehsrghrrghvrghnrghksehgohhoghhlvgdrtghomhdprhgtphhtthhopegshhgvlhhgrggrshesghhoohhglhgvrdgtohhmpdhrtghpthhtoheplhhiiihhihdrhhhouhesrghmugdrtghomhdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-GND-Sasl: herve.codina@bootlin.com An of_node can be set to a device using device_set_node(). This function cannot prevent any of_node and/or fwnode overwrites. When adding an of_node on an already present device, the following operations need to be done: - Attach the of_node if no of_node were already attached - Attach the of_node as a fwnode if no fwnode were already attached This is the purpose of device_add_of_node(). device_remove_of_node() reverts the operations done by device_add_of_node(). Signed-off-by: Herve Codina --- drivers/base/core.c | 61 ++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 63 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 5a1f05198114..d1b044af64de 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -5170,6 +5170,67 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode) } EXPORT_SYMBOL_GPL(set_secondary_fwnode); +/** + * device_remove_of_node - Remove an of_node from a device + * @dev: device whose device-tree node is being removed + */ +void device_remove_of_node(struct device *dev) +{ + dev = get_device(dev); + if (!dev) + return; + + if (!dev->of_node) + goto end; + + if (dev->fwnode == of_fwnode_handle(dev->of_node)) + dev->fwnode = NULL; + + of_node_put(dev->of_node); + dev->of_node = NULL; + +end: + put_device(dev); +} +EXPORT_SYMBOL_GPL(device_remove_of_node); + +/** + * device_add_of_node - Add an of_node to an existing device + * @dev: device whose device-tree node is being added + * @of_node: of_node to add + * + * Return: 0 on success or error code on failure. + */ +int device_add_of_node(struct device *dev, struct device_node *of_node) +{ + int ret; + + if (!of_node) + return -EINVAL; + + dev = get_device(dev); + if (!dev) + return -EINVAL; + + if (dev->of_node) { + dev_err(dev, "Cannot replace node %pOF with %pOF\n", + dev->of_node, of_node); + ret = -EBUSY; + goto end; + } + + dev->of_node = of_node_get(of_node); + + if (!dev->fwnode) + dev->fwnode = of_fwnode_handle(of_node); + + ret = 0; +end: + put_device(dev); + return ret; +} +EXPORT_SYMBOL_GPL(device_add_of_node); + /** * device_set_of_node_from_dev - reuse device-tree node of another device * @dev: device whose device-tree node is being set diff --git a/include/linux/device.h b/include/linux/device.h index 80a5b3268986..1244e5892292 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1191,6 +1191,8 @@ int device_online(struct device *dev); void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode); void device_set_node(struct device *dev, struct fwnode_handle *fwnode); +int device_add_of_node(struct device *dev, struct device_node *of_node); +void device_remove_of_node(struct device *dev); void device_set_of_node_from_dev(struct device *dev, const struct device *dev2); static inline struct device_node *dev_of_node(struct device *dev) From patchwork Tue Feb 4 07:34:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 13958733 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) (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 EB2F7204C1D; Tue, 4 Feb 2025 07:35:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654519; cv=none; b=u5P+medRJ+tIokSmRYU7IxyD5R0qX9gOR8I/zPNgvJ9E92nDU/DDiyVynfoM+7mXwJoftl7kTwtIAcovzNdKMZ6X3FlhOoUOpvuy2sJ4bhQagoc7vSuzOgp7L4pYJDNpyLGaKr30Y0zfAMLkTbt4qoxgHUDHLLrmfzYLk8SLpYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654519; c=relaxed/simple; bh=2M503OvHvoRmWCpank1mJVuBmwGQs429DHHS9kKURYc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=obZZBMk/WBpLUPa3Vmb0v+MQl/09o6NlJWn/PsnG2iaGeC06N4y/FxARirZu6c1TE1AOjRYGpQ8ibN9qdwvcjWGSciKFIC1XtI9UVdLcXzA6DlhYLnBAtqLbkTWosxgjlgVJXV3VVkI5fkfKAefnffZIMJsrckil8fEjL+k107s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=jndpBWda; arc=none smtp.client-ip=217.70.183.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="jndpBWda" Received: by mail.gandi.net (Postfix) with ESMTPA id 7344A44402; Tue, 4 Feb 2025 07:35:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1738654514; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xiD8UramHvEcUARfSgVu7SkVw5gcFuebpD/DDan/ap8=; b=jndpBWdasbdVCWWTfVXW/szfj7rzjQLn0kzL8T4SsTmN+JWSTBxnAdAhRUfs+j/X9NV+fY DcbS3JU5QMNrORc2U8iwzPP9Imxj3n34vjpdO7TsdRBCdCPOzr280O8eaOB+ucbDTAmakJ IcDLQ7eZp8x1J7bVKbcIjJt1eOa+FLHgfEUAhyUUnWRYSEsI03Fd6l6LRrv2EuphsDsSJC aIAp3n0cApOIyyQrv4z+7R77YJSMRWTkhaGShpbAoihbHBooEZsLkxt3yRj16LpezXMdaS cuAm4DZXns+TaBILwNDf4LNh91Am3LdFqmSNQ9JrFVa6q/rsXUVlxqNGS7gNFw== From: Herve Codina To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Rob Herring , Saravana Kannan , Bjorn Helgaas , Lizhi Hou Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Herve Codina Subject: [PATCH v7 2/5] PCI: of: Use device_{add,remove}_of_node() to attach of_node to existing device Date: Tue, 4 Feb 2025 08:34:57 +0100 Message-ID: <20250204073501.278248-3-herve.codina@bootlin.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250204073501.278248-1-herve.codina@bootlin.com> References: <20250204073501.278248-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduleelvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepjfgvrhhvvgcuvehoughinhgruceohhgvrhhvvgdrtghoughinhgrsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehffeigfejueelueeuffelueefgfelhfejhfehieegudekteeiledttdfhffekffenucfkphepvdgrtddumegvtdgrmedvgeeimeejjeeltdemvdeitgegmegvvddvmeeitdefugemheekrgenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepihhnvghtpedvrgdtudemvgdtrgemvdegieemjeejledtmedviegtgeemvgdvvdemiedtfegumeehkegrpdhhvghloheplhhotggrlhhhohhsthdrlhhotggrlhguohhmrghinhdpmhgrihhlfhhrohhmpehhvghrvhgvrdgtohguihhnrgessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepudehpdhrtghpthhtohepghhrvghgkhhhsehlihhnuhigfhhouhhnuggrthhiohhnrdhorhhgpdhrtghpthhtoheprhgrfhgrvghlsehkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghkrheskhgvrhhnvghlrdhorhhgpdhrtghpthhtoheprhhosghhsehkvghrn hgvlhdrohhrghdprhgtphhtthhopehsrghrrghvrghnrghksehgohhoghhlvgdrtghomhdprhgtphhtthhopegshhgvlhhgrggrshesghhoohhglhgvrdgtohhmpdhrtghpthhtoheplhhiiihhihdrhhhouhesrghmugdrtghomhdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-GND-Sasl: herve.codina@bootlin.com The commit 407d1a51921e ("PCI: Create device tree node for bridge") creates of_node for PCI devices. The newly created of_node is attached to an existing device. This is done setting directly pdev->dev.of_node in the code. Even if pdev->dev.of_node cannot be previously set, this doesn't handle the fwnode field of the struct device. Indeed, this field needs to be set if it hasn't already been set. device_{add,remove}_of_node() have been introduced to handle this case. Use them instead of the direct setting. Signed-off-by: Herve Codina --- drivers/pci/of.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 7a806f5c0d20..fb5e6da1ead0 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -653,8 +653,8 @@ void of_pci_remove_node(struct pci_dev *pdev) np = pci_device_to_OF_node(pdev); if (!np || !of_node_check_flag(np, OF_DYNAMIC)) return; - pdev->dev.of_node = NULL; + device_remove_of_node(&pdev->dev); of_changeset_revert(np->data); of_changeset_destroy(np->data); of_node_put(np); @@ -711,11 +711,18 @@ void of_pci_make_dev_node(struct pci_dev *pdev) goto out_free_node; np->data = cset; - pdev->dev.of_node = np; + + ret = device_add_of_node(&pdev->dev, np); + if (ret) + goto out_revert_cset; + kfree(name); return; +out_revert_cset: + np->data = NULL; + of_changeset_revert(cset); out_free_node: of_node_put(np); out_destroy_cset: From patchwork Tue Feb 4 07:34:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 13958735 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) (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 37A562063D8; Tue, 4 Feb 2025 07:35:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654520; cv=none; b=hcNBXCVOsertZMY8W2RBzLz5CkuILxkuvkkPUCEIEGFQXn5CkgjK1yeifB+w43LPua5rLmWID/Cc9ogKDdmk+s9s6uxP4JrQNzQEudPAmOGlUZjQrPevFxckXzEdX9FUkRiFLvj92R/OwwyZXgp4OlKiW66XTAfVWZ+0+MPPxUY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654520; c=relaxed/simple; bh=aQTmqsYg4zzaDJRji9aqlWjSXghEmXNU3CBY2xcegJY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YuzBfIVvpcBj02Lf4iKIoQdy3uKCOvJ9sovk/aeW87cLFpPoi07eYJJf6B1BVU6rT8fpi4oS2Hn72MbDGl1YjiHkUOxmaCKrg+tjabIgmDrjNoYVbAZnqxOWpid015Z7gN7hgMxa53tj1zpXkzawr8PB8hEuV1j3+nrL3RS09IM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Cxmzxd1y; arc=none smtp.client-ip=217.70.183.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Cxmzxd1y" Received: by mail.gandi.net (Postfix) with ESMTPA id 3D38F4440A; Tue, 4 Feb 2025 07:35:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1738654514; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XI9aiHv/12/f3NIcFxYC4k1Bz6f0d7w4zpDQLTo4OHo=; b=Cxmzxd1yT2r9H1X2hEFyQ9s5t+JDu26mDP9tfHu2DiDpW2Z8Nc/iGtUMWNzYvgWhrtz+Rs 09rv5lg3HbvzNWox9Bag9UruXopbr8jTZQnq7MHlgnBt7zYw7cToGIGOjdgrXdJ9nXTm2s ytSGYPqNo53FXWk1Gi2oThlAgqvvqteM1o+gEMomlwRH1vormfvZCeUxLuN49MCbYSDiYd w9R4SC4HtCUnvcmDb6AsBE2KwvTTfCn9dkPsp76ZAmHtVERhGEWpAdYewK9NrqGl9sd7lA zLJtpkvGfKYgkLxpLBSj5TI7pUq9ryAMuSM2B6GrJq+7wJmnyzTp205nT9qveA== From: Herve Codina To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Rob Herring , Saravana Kannan , Bjorn Helgaas , Lizhi Hou Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Herve Codina Subject: [PATCH v7 3/5] PCI: of_property: Add support for NULL pdev in of_pci_set_address() Date: Tue, 4 Feb 2025 08:34:58 +0100 Message-ID: <20250204073501.278248-4-herve.codina@bootlin.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250204073501.278248-1-herve.codina@bootlin.com> References: <20250204073501.278248-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduleelvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepjfgvrhhvvgcuvehoughinhgruceohhgvrhhvvgdrtghoughinhgrsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehffeigfejueelueeuffelueefgfelhfejhfehieegudekteeiledttdfhffekffenucfkphepvdgrtddumegvtdgrmedvgeeimeejjeeltdemvdeitgegmegvvddvmeeitdefugemheekrgenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepihhnvghtpedvrgdtudemvgdtrgemvdegieemjeejledtmedviegtgeemvgdvvdemiedtfegumeehkegrpdhhvghloheplhhotggrlhhhohhsthdrlhhotggrlhguohhmrghinhdpmhgrihhlfhhrohhmpehhvghrvhgvrdgtohguihhnrgessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepudehpdhrtghpthhtohepghhrvghgkhhhsehlihhnuhigfhhouhhnuggrthhiohhnrdhorhhgpdhrtghpthhtoheprhgrfhgrvghlsehkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghkrheskhgvrhhnvghlrdhorhhgpdhrtghpthhtoheprhhosghhsehkvghrn hgvlhdrohhrghdprhgtphhtthhopehsrghrrghvrghnrghksehgohhoghhlvgdrtghomhdprhgtphhtthhopegshhgvlhhgrggrshesghhoohhglhgvrdgtohhmpdhrtghpthhtoheplhhiiihhihdrhhhouhesrghmugdrtghomhdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-GND-Sasl: herve.codina@bootlin.com The pdev (pointer to a struct pci_dev) parameter of of_pci_set_address() cannot be NULL. In order to reuse of_pci_set_address() when creating the PCI root bus node, this function needs to support a NULL pdev parameter. Indeed, in the case of the PCI root bus node creation, no pdev are available and of_pci_set_address() will be used with the bridge windows. Allow to call of_pci_set_address() with a NULL pdev. Signed-off-by: Herve Codina --- drivers/pci/of_property.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 58fbafac7c6a..962d2e8cc095 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -54,9 +54,13 @@ enum of_pci_prop_compatible { static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr, u32 reg_num, u32 flags, bool reloc) { - prop[0] = FIELD_PREP(OF_PCI_ADDR_FIELD_BUS, pdev->bus->number) | - FIELD_PREP(OF_PCI_ADDR_FIELD_DEV, PCI_SLOT(pdev->devfn)) | - FIELD_PREP(OF_PCI_ADDR_FIELD_FUNC, PCI_FUNC(pdev->devfn)); + if (pdev) + prop[0] = FIELD_PREP(OF_PCI_ADDR_FIELD_BUS, pdev->bus->number) | + FIELD_PREP(OF_PCI_ADDR_FIELD_DEV, PCI_SLOT(pdev->devfn)) | + FIELD_PREP(OF_PCI_ADDR_FIELD_FUNC, PCI_FUNC(pdev->devfn)); + else + prop[0] = 0; + prop[0] |= flags | reg_num; if (!reloc) { prop[0] |= OF_PCI_ADDR_FIELD_NONRELOC; From patchwork Tue Feb 4 07:34:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 13958734 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) (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 39D9A2063DA; Tue, 4 Feb 2025 07:35:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654520; cv=none; b=bJaLgXKsJiRUmLva4vzGiAFJb+5bsVBYEjDPGHCTysq5CzjXWyHD//lg1HAToLsfFGVEwjOyi7+rGo2ziIfM3S8aoubStRxWq1DlTY0E42dndYLDALBXYAZEYmgcVkePb7T/SijgoLXOrjW4m/TPEWG0TNz4TrljbwzQnf/xmkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654520; c=relaxed/simple; bh=Z92Iij4ppO//2iG1VjApoeSswpj3ZvFmkzJ2X3J/kqM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ofosoWnHfqoxhnCeOCrAEsejKCtrnWu7/A54bAPLRvbbQemyvx+5tzBpIqFBHhoFTtV8I5w3hAkNHkUkznPji8crv1J1eglzGiiCKnM+8aMAxnSyAbFeArDbvpvJO+Eb0uJ7Qw8Dkx1CHq/f4GIsxOukS6+NVmGxBD+x3ZNdx80= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=mS2Vuabh; arc=none smtp.client-ip=217.70.183.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="mS2Vuabh" Received: by mail.gandi.net (Postfix) with ESMTPA id 0722144417; Tue, 4 Feb 2025 07:35:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1738654515; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CmiwcnqKRWvJz2/o0/LToxXtK0VEDLbdaqIJoBX7Vg4=; b=mS2Vuabhq4EJiME1PPuz0umI4Sck4sQZkUt3NkBUcNUUcS/obFp8j+MgjqNriQio0pbFsE xyuU4h1bFUl5vRZulfvBhI4sO0NFdoQvG+O2eLHMr0gxhEnyT5tJagg+R8E6lHqFiytgOk qQ5LLkb3HNMzv3WA0AW9YiCeFkWLf5tvHXL/0YnGTuovNxmYmCsUUPyvZu1fqhci6YYAnx 88WTniYkG672xKWfXrsSqAiUP8J6uILKrp0r70wpwGlhMGIZnei+qW/Cyn/SuM9WrDuXYB BzhK48hpTqsrD0w13YqiagR4CUD3xpbKNh6HiJHcX/iwID/jWvmxhd9im+8B+g== From: Herve Codina To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Rob Herring , Saravana Kannan , Bjorn Helgaas , Lizhi Hou Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Herve Codina Subject: [PATCH v7 4/5] PCI: of_property: Constify parameter in of_pci_get_addr_flags() Date: Tue, 4 Feb 2025 08:34:59 +0100 Message-ID: <20250204073501.278248-5-herve.codina@bootlin.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250204073501.278248-1-herve.codina@bootlin.com> References: <20250204073501.278248-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduleelvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepjfgvrhhvvgcuvehoughinhgruceohhgvrhhvvgdrtghoughinhgrsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehffeigfejueelueeuffelueefgfelhfejhfehieegudekteeiledttdfhffekffenucfkphepvdgrtddumegvtdgrmedvgeeimeejjeeltdemvdeitgegmegvvddvmeeitdefugemheekrgenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepihhnvghtpedvrgdtudemvgdtrgemvdegieemjeejledtmedviegtgeemvgdvvdemiedtfegumeehkegrpdhhvghloheplhhotggrlhhhohhsthdrlhhotggrlhguohhmrghinhdpmhgrihhlfhhrohhmpehhvghrvhgvrdgtohguihhnrgessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepudehpdhrtghpthhtohepghhrvghgkhhhsehlihhnuhigfhhouhhnuggrthhiohhnrdhorhhgpdhrtghpthhtoheprhgrfhgrvghlsehkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghkrheskhgvrhhnvghlrdhorhhgpdhrtghpthhtoheprhhosghhsehkvghrn hgvlhdrohhrghdprhgtphhtthhopehsrghrrghvrghnrghksehgohhoghhlvgdrtghomhdprhgtphhtthhopegshhgvlhhgrggrshesghhoohhglhgvrdgtohhmpdhrtghpthhtoheplhhiiihhihdrhhhouhesrghmugdrtghomhdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-GND-Sasl: herve.codina@bootlin.com The res parameter has no reason to be a pointer to an un-const struct resource. Indeed, struct resource is not supposed to be modified by the function. Constify the res parameter. Signed-off-by: Herve Codina --- drivers/pci/of_property.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 962d2e8cc095..b17dcb04de18 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -69,7 +69,7 @@ static void of_pci_set_address(struct pci_dev *pdev, u32 *prop, u64 addr, } } -static int of_pci_get_addr_flags(struct resource *res, u32 *flags) +static int of_pci_get_addr_flags(const struct resource *res, u32 *flags) { u32 ss; From patchwork Tue Feb 4 07:35:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 13958736 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) (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 37AF42063D9; Tue, 4 Feb 2025 07:35:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654520; cv=none; b=qItqrzjFwSFSAsJlwemgOaP+C4VnphF3ZCyxq8imbC94Z0lSdCKF8bl54mhACNfZonSVixgm6RVG1dQ4/aHIRAJ7JiIFllqrX8mZ2AmpBL/cJe5kbCF/fmolO/Kfxjsjp7OJaQ0PBT6iUIxetvnRJBGgN0OTbxzyAzrGjWWa8So= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738654520; c=relaxed/simple; bh=NJFVByEsqDIs0tIZI9Kx7a7UBqt4tLzK4Hvnn4pLkXU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Laz1GDzJMvljm2KYDMCvDqnHUFWPkQqREz+w/j5e3+KWjlZrutkCcq4WWEJpxcEalgTouv9tvG0ONCEhv+VlIWaC0mYZGYejtLIQWsF/H9SKMvva4hXA454ffiecf7RZiWhQmbDvBMWvZYBetQQj4pivM4nwemhmbp+zw7dcoKA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=VrtTe12k; arc=none smtp.client-ip=217.70.183.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="VrtTe12k" Received: by mail.gandi.net (Postfix) with ESMTPA id D519544413; Tue, 4 Feb 2025 07:35:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1738654516; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BDNBdquI1LOY2klmHVN/9o1smostCi+fz47ziwBefps=; b=VrtTe12kISdoYSTy68J/yDQSOfVc5/pHXvUukcQ3dy2GQyUdSbPGv3KzSImjQK2WMJgOfu yN4rTJjwTOJRtDsQShuffu96mJ/q6dl/VulFjS5r3EayI3IQQ4KlNLKgrgknxoI/VCRWsS wzSDApDizsISm+Hzsrs9EQsfFOWI2AfkZJ+XkIZKHJDjwIS4kLnmL9qv+l+aBVB0F+0s2L 8pyy8rzXh1A00y6+YJOD5TPWuKNgPdHXltnkC8DX7/0zl7NAdC+/MUhUgiEFMnYgHBn+Lc oO2vPjq6WOen9J0WXcft4Pwu7weKt60Hb59hK4Kw74oWHLZV6RQxlaRiqxMyjA== From: Herve Codina To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Rob Herring , Saravana Kannan , Bjorn Helgaas , Lizhi Hou Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Allan Nielsen , Horatiu Vultur , Steen Hegelund , Thomas Petazzoni , Herve Codina Subject: [PATCH v7 5/5] PCI: of: Create device-tree PCI host bridge node Date: Tue, 4 Feb 2025 08:35:00 +0100 Message-ID: <20250204073501.278248-6-herve.codina@bootlin.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250204073501.278248-1-herve.codina@bootlin.com> References: <20250204073501.278248-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-State: clean X-GND-Score: -100 X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduleelvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfitefpfffkpdcuggftfghnshhusghstghrihgsvgenuceurghilhhouhhtmecufedtudenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepjfgvrhhvvgcuvehoughinhgruceohhgvrhhvvgdrtghoughinhgrsegsohhothhlihhnrdgtohhmqeenucggtffrrghtthgvrhhnpeehffeigfejueelueeuffelueefgfelhfejhfehieegudekteeiledttdfhffekffenucfkphepvdgrtddumegvtdgrmedvgeeimeejjeeltdemvdeitgegmegvvddvmeeitdefugemheekrgenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepihhnvghtpedvrgdtudemvgdtrgemvdegieemjeejledtmedviegtgeemvgdvvdemiedtfegumeehkegrpdhhvghloheplhhotggrlhhhohhsthdrlhhotggrlhguohhmrghinhdpmhgrihhlfhhrohhmpehhvghrvhgvrdgtohguihhnrgessghoohhtlhhinhdrtghomhdpnhgspghrtghpthhtohepudehpdhrtghpthhtohepghhrvghgkhhhsehlihhnuhigfhhouhhnuggrthhiohhnrdhorhhgpdhrtghpthhtoheprhgrfhgrvghlsehkvghrnhgvlhdrohhrghdprhgtphhtthhopegurghkrheskhgvrhhnvghlrdhorhhgpdhrtghpthhtoheprhhosghhsehkvghrn hgvlhdrohhrghdprhgtphhtthhopehsrghrrghvrghnrghksehgohhoghhlvgdrtghomhdprhgtphhtthhopegshhgvlhhgrggrshesghhoohhglhgvrdgtohhmpdhrtghpthhtoheplhhiiihhihdrhhhouhesrghmugdrtghomhdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-GND-Sasl: herve.codina@bootlin.com PCI devices device-tree nodes can be already created. This was introduced by commit 407d1a51921e ("PCI: Create device tree node for bridge"). In order to have device-tree nodes related to PCI devices attached on their PCI root bus (the PCI bus handled by the PCI host bridge), a PCI root bus device-tree node is needed. This root bus node will be used as the parent node of the first level devices scanned on the bus. On device-tree based systems, this PCI root bus device tree node is set to the node of the related PCI host bridge. The PCI host bridge node is available in the device-tree used to describe the hardware passed at boot. On non device-tree based system (such as ACPI), a device-tree node for the PCI host bridge or for the root bus does not exist. Indeed, the PCI host bridge is not described in a device-tree used at boot simply because no device-tree are passed at boot. The device-tree PCI host bridge node creation needs to be done at runtime. This is done in the same way as for the creation of the PCI device nodes. I.e. node and properties are created based on computed information done by the PCI core. Also, as is done on device-tree based systems, this PCI host bridge node is used for the PCI root bus. Signed-off-by: Herve Codina --- drivers/pci/of.c | 104 +++++++++++++++++++++++++++++++++++++- drivers/pci/of_property.c | 102 +++++++++++++++++++++++++++++++++++++ drivers/pci/pci.h | 6 +++ drivers/pci/probe.c | 2 + drivers/pci/remove.c | 2 + 5 files changed, 215 insertions(+), 1 deletion(-) diff --git a/drivers/pci/of.c b/drivers/pci/of.c index fb5e6da1ead0..c59429e909c0 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -731,7 +731,109 @@ void of_pci_make_dev_node(struct pci_dev *pdev) out_free_name: kfree(name); } -#endif + +void of_pci_remove_host_bridge_node(struct pci_host_bridge *bridge) +{ + struct device_node *np; + + np = pci_bus_to_OF_node(bridge->bus); + if (!np || !of_node_check_flag(np, OF_DYNAMIC)) + return; + + device_remove_of_node(&bridge->bus->dev); + device_remove_of_node(&bridge->dev); + of_changeset_revert(np->data); + of_changeset_destroy(np->data); + of_node_put(np); +} + +void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge) +{ + struct device_node *np = NULL; + struct of_changeset *cset; + const char *name; + int ret; + + /* + * If there is already a device-tree node linked to the PCI bus handled + * by this bridge (i.e. the PCI root bus), nothing to do. + */ + if (pci_bus_to_OF_node(bridge->bus)) + return; + + /* The root bus has no node. Check that the host bridge has no node too */ + if (bridge->dev.of_node) { + dev_err(&bridge->dev, "PCI host bridge of_node already set"); + return; + } + + /* Check if there is a DT root node to attach the created node */ + if (!of_root) { + pr_err("of_root node is NULL, cannot create PCI host bridge node\n"); + return; + } + + name = kasprintf(GFP_KERNEL, "pci@%x,%x", pci_domain_nr(bridge->bus), + bridge->bus->number); + if (!name) + return; + + cset = kmalloc(sizeof(*cset), GFP_KERNEL); + if (!cset) + goto out_free_name; + of_changeset_init(cset); + + np = of_changeset_create_node(cset, of_root, name); + if (!np) + goto out_destroy_cset; + + ret = of_pci_add_host_bridge_properties(bridge, cset, np); + if (ret) + goto out_free_node; + + /* + * This of_node will be added to an existing device. The of_node parent + * is the root OF node and so this node will be handled by the platform + * bus. Avoid any new device creation. + */ + of_node_set_flag(np, OF_POPULATED); + np->fwnode.dev = &bridge->dev; + fwnode_dev_initialized(&np->fwnode, true); + + ret = of_changeset_apply(cset); + if (ret) + goto out_free_node; + + np->data = cset; + + /* Add the of_node to host bridge and the root bus */ + ret = device_add_of_node(&bridge->dev, np); + if (ret) + goto out_revert_cset; + + ret = device_add_of_node(&bridge->bus->dev, np); + if (ret) + goto out_remove_bridge_dev_of_node; + + kfree(name); + + return; + +out_remove_bridge_dev_of_node: + device_remove_of_node(&bridge->dev); +out_revert_cset: + np->data = NULL; + of_changeset_revert(cset); +out_free_node: + of_node_put(np); +out_destroy_cset: + of_changeset_destroy(cset); + kfree(cset); +out_free_name: + kfree(name); +} + +#endif /* CONFIG_PCI_DYNAMIC_OF_NODES */ /** * of_pci_supply_present() - Check if the power supply is present for the PCI diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index b17dcb04de18..e0069c9eb23f 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -394,3 +394,105 @@ int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs, return 0; } + +static bool of_pci_is_range_resource(const struct resource *res, u32 *flags) +{ + if (!(resource_type(res) & IORESOURCE_MEM) && + !(resource_type(res) & IORESOURCE_MEM_64)) + return false; + + if (of_pci_get_addr_flags(res, flags)) + return false; + + return true; +} + +static int of_pci_host_bridge_prop_ranges(struct pci_host_bridge *bridge, + struct of_changeset *ocs, + struct device_node *np) +{ + struct resource_entry *window; + unsigned int ranges_sz = 0; + unsigned int n_range = 0; + struct resource *res; + int n_addr_cells; + u32 *ranges; + u64 val64; + u32 flags; + int ret; + + n_addr_cells = of_n_addr_cells(np); + if (n_addr_cells <= 0 || n_addr_cells > 2) + return -EINVAL; + + resource_list_for_each_entry(window, &bridge->windows) { + res = window->res; + if (!of_pci_is_range_resource(res, &flags)) + continue; + n_range++; + } + + if (!n_range) + return 0; + + ranges = kcalloc(n_range, + (OF_PCI_ADDRESS_CELLS + OF_PCI_SIZE_CELLS + + n_addr_cells) * sizeof(*ranges), + GFP_KERNEL); + if (!ranges) + return -ENOMEM; + + resource_list_for_each_entry(window, &bridge->windows) { + res = window->res; + if (!of_pci_is_range_resource(res, &flags)) + continue; + + /* PCI bus address */ + val64 = res->start; + of_pci_set_address(NULL, &ranges[ranges_sz], val64 - window->offset, + 0, flags, false); + ranges_sz += OF_PCI_ADDRESS_CELLS; + + /* Host bus address */ + if (n_addr_cells == 2) + ranges[ranges_sz++] = upper_32_bits(val64); + ranges[ranges_sz++] = lower_32_bits(val64); + + /* Size */ + val64 = resource_size(res); + ranges[ranges_sz] = upper_32_bits(val64); + ranges[ranges_sz + 1] = lower_32_bits(val64); + ranges_sz += OF_PCI_SIZE_CELLS; + } + + ret = of_changeset_add_prop_u32_array(ocs, np, "ranges", ranges, ranges_sz); + kfree(ranges); + return ret; +} + +int of_pci_add_host_bridge_properties(struct pci_host_bridge *bridge, + struct of_changeset *ocs, + struct device_node *np) +{ + int ret; + + ret = of_changeset_add_prop_string(ocs, np, "device_type", "pci"); + if (ret) + return ret; + + ret = of_changeset_add_prop_u32(ocs, np, "#address-cells", + OF_PCI_ADDRESS_CELLS); + if (ret) + return ret; + + ret = of_changeset_add_prop_u32(ocs, np, "#size-cells", + OF_PCI_SIZE_CELLS); + if (ret) + return ret; + + ret = of_pci_host_bridge_prop_ranges(bridge, ocs, np); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 01e51db8d285..f916d0f386a2 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -876,9 +876,15 @@ void of_pci_make_dev_node(struct pci_dev *pdev); void of_pci_remove_node(struct pci_dev *pdev); int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs, struct device_node *np); +void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge); +void of_pci_remove_host_bridge_node(struct pci_host_bridge *bridge); +int of_pci_add_host_bridge_properties(struct pci_host_bridge *bridge, struct of_changeset *ocs, + struct device_node *np); #else static inline void of_pci_make_dev_node(struct pci_dev *pdev) { } static inline void of_pci_remove_node(struct pci_dev *pdev) { } +static inline void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge) { } +static inline void of_pci_remove_host_bridge_node(struct pci_host_bridge *bridge) { } #endif #ifdef CONFIG_PCIEAER diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b6536ed599c3..b74a12a0193a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1094,6 +1094,8 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) dev_info(&bus->dev, "root bus resource %pR%s\n", res, addr); } + of_pci_make_host_bridge_node(bridge); + down_write(&pci_bus_sem); list_add_tail(&bus->node, &pci_root_buses); up_write(&pci_bus_sem); diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index efc37fcb73e2..9f7df2b20183 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -163,6 +163,8 @@ void pci_stop_root_bus(struct pci_bus *bus) &bus->devices, bus_list) pci_stop_bus_device(child); + of_pci_remove_host_bridge_node(host_bridge); + /* stop the host bridge */ device_release_driver(&host_bridge->dev); }