* [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation.
@ 2024-12-02 13:15 Herve Codina
2024-12-02 13:15 ` [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node() Herve Codina
` (5 more replies)
0 siblings, 6 replies; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
Hi,
This series adds support for creating a device-tree node for the PCI
host bridge on non device-tree based system.
Creating device-tree nodes for PCI devices and PCI-PCI bridges already
exists upstream. It was added in commit 407d1a51921e ("PCI: Create
device tree node for bridge"). Created device-tree nodes need a parent
node to be attached to. For the first level devices, on device-tree
based system, this parent node (i.e. the PCI host bridge) is described
in the base device-tree. The PCI bus related to this bridge (PCI root
bus) inherit of the PCI host bridge device-tree node.
The LAN966x PCI device driver, available since commit 185686beb464
("misc: Add support for LAN966x PCI device"), relies on this feature.
On system where the base hardware is not described by a device-tree, the
PCI host bridge to which first level created PCI devices need to be
attach to does not exist. This is the case for instance on ACPI
described systems such as x86.
This series goal is to handle this case.
In order to have the PCI host bridge device-tree node available even
on x86, this top level node is created (if not already present) based on
information computed by the PCI core. It follows the same mechanism as
the one used for PCI devices device-tree node creation.
As for device-tree based system, the PCI root bus handled by the PCI
host bridge inherit of this created node.
In order to have this feature available, a number of changes are needed:
- Patch 1 and 2: Introduce and use device_{add,remove}_of_node().
This function will also be used in the root PCI bus node creation.
- Patch 3 and 4: Improve existing functions to reuse them in the root
PCI bus node creation.
- Patch 5: Set #address-cells and #size-cells in the empty device-tree
root node.
- Patch 6: The PCI host bridge device-tree node creation itself.
With those modifications, the LAN966x PCI device is working on x86 systems
and all device-tree kunit tests (including the of_unittest_pci_node test)
pass successfully with the following command:
qemu-system-x86_64 -machine q35 -nographic \
-kernel arch/x86_64/boot/bzImage --append console=ttyS0 \
-device pcie-root-port,port=0x10,chassis=9,id=pci.9,bus=pcie.0,multifunction=on,addr=0x3 \
-device pcie-root-port,port=0x11,chassis=10,id=pci.10,bus=pcie.0,addr=0x3.0x1 \
-device x3130-upstream,id=pci.11,bus=pci.9,addr=0x0 \
-device xio3130-downstream,port=0x0,chassis=11,id=pci.12,bus=pci.11,multifunction=on,addr=0x0 \
-device i82801b11-bridge,id=pci.13,bus=pcie.0,addr=0x4 \
-device pci-bridge,chassis_nr=14,id=pci.14,bus=pci.13,addr=0x0 \
-device pci-testdev,bus=pci.12,addr=0x0
Compare to previous iteration, this v4 series has no changes but
patches have been rebased on top of v6.13-rc1.
Best regards,
Hervé Codina
Changes v3 -> v4
v3: https://lore.kernel.org/lkml/20241114165446.611458-1-herve.codina@bootlin.com/
Rebase on top of v6.13-rc1
- Patches 1 to 6
No changes
Changes v2 -> v3
v2: https://lore.kernel.org/lkml/20241108143600.756224-1-herve.codina@bootlin.com/
- Patch 5
Fix commit log.
Use 2 for #size-cells.
- Patches 1 to 4 and 6
No changes
Changes v1 -> v2
v1: https://lore.kernel.org/lkml/20241104172001.165640-1-herve.codina@bootlin.com/
- Patch 1
Remove Cc: stable
- Patch 2
Remove Fixup tag and Cc: stable
- Patches 3 and 4
No changes
- Patch 5
Add #address-cells/#size-cells in the empty root DT node instead of
updating default values for x86.
Update commit log and commit title.
- Patch 6
Create device-tree node for the PCI host bridge and reuse it for
the PCI root bus. Rename functions accordingly.
Use "pci" instead of "pci-root" for the PCI host bridge node name.
Use "res->start - windows->offset" for the PCI bus addresses.
Update commit log and commit title.
Herve Codina (6):
driver core: Introduce device_{add,remove}_of_node()
PCI: of: Use device_{add,remove}_of_node() to attach of_node to
existing device
PCI: of_property: Add support for NULL pdev in of_pci_set_address()
PCI: of_property: Constify parameter in of_pci_get_addr_flags()
of: Add #address-cells/#size-cells in the device-tree root empty node
PCI: of: Create device-tree PCI host bridge node
drivers/base/core.c | 52 +++++++++++++++++
drivers/of/empty_root.dts | 9 ++-
drivers/pci/of.c | 98 +++++++++++++++++++++++++++++++-
drivers/pci/of_property.c | 114 ++++++++++++++++++++++++++++++++++++--
drivers/pci/pci.h | 6 ++
drivers/pci/probe.c | 2 +
drivers/pci/remove.c | 2 +
include/linux/device.h | 2 +
8 files changed, 277 insertions(+), 8 deletions(-)
--
2.47.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node()
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
@ 2024-12-02 13:15 ` Herve Codina
2024-12-04 21:38 ` Bjorn Helgaas
2024-12-02 13:15 ` [PATCH v4 2/6] PCI: of: Use device_{add,remove}_of_node() to attach of_node to existing device Herve Codina
` (4 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
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 <herve.codina@bootlin.com>
---
drivers/base/core.c | 52 ++++++++++++++++++++++++++++++++++++++++++
include/linux/device.h | 2 ++
2 files changed, 54 insertions(+)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 8b056306f04e..3953c5ab7316 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -5216,6 +5216,58 @@ 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
+ */
+void device_add_of_node(struct device *dev, struct device_node *of_node)
+{
+ if (!of_node)
+ return;
+
+ dev = get_device(dev);
+ if (!dev)
+ return;
+
+ if (WARN(dev->of_node, "%s: Cannot replace node %pOF with %pOF\n",
+ dev_name(dev), dev->of_node, of_node))
+ goto end;
+
+ dev->of_node = of_node_get(of_node);
+
+ if (!dev->fwnode)
+ dev->fwnode = of_fwnode_handle(of_node);
+
+end:
+ put_device(dev);
+}
+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 667cb6db9019..ef4c0f3c41cd 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1149,6 +1149,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);
+void 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)
--
2.47.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 2/6] PCI: of: Use device_{add,remove}_of_node() to attach of_node to existing device
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
2024-12-02 13:15 ` [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node() Herve Codina
@ 2024-12-02 13:15 ` Herve Codina
2024-12-02 13:15 ` [PATCH v4 3/6] PCI: of_property: Add support for NULL pdev in of_pci_set_address() Herve Codina
` (3 subsequent siblings)
5 siblings, 0 replies; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
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 <herve.codina@bootlin.com>
---
drivers/pci/of.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 52f770bcc481..3cca33105b85 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -655,8 +655,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);
@@ -713,7 +713,7 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
goto out_free_node;
np->data = cset;
- pdev->dev.of_node = np;
+ device_add_of_node(&pdev->dev, np);
kfree(name);
return;
--
2.47.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 3/6] PCI: of_property: Add support for NULL pdev in of_pci_set_address()
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
2024-12-02 13:15 ` [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node() Herve Codina
2024-12-02 13:15 ` [PATCH v4 2/6] PCI: of: Use device_{add,remove}_of_node() to attach of_node to existing device Herve Codina
@ 2024-12-02 13:15 ` Herve Codina
2024-12-02 13:15 ` [PATCH v4 4/6] PCI: of_property: Constify parameter in of_pci_get_addr_flags() Herve Codina
` (2 subsequent siblings)
5 siblings, 0 replies; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
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 <herve.codina@bootlin.com>
---
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 886c236e5de6..8aff9ca1f222 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;
--
2.47.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 4/6] PCI: of_property: Constify parameter in of_pci_get_addr_flags()
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
` (2 preceding siblings ...)
2024-12-02 13:15 ` [PATCH v4 3/6] PCI: of_property: Add support for NULL pdev in of_pci_set_address() Herve Codina
@ 2024-12-02 13:15 ` Herve Codina
2024-12-02 13:15 ` [PATCH v4 5/6] of: Add #address-cells/#size-cells in the device-tree root empty node Herve Codina
2024-12-02 13:15 ` [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node Herve Codina
5 siblings, 0 replies; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
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 <herve.codina@bootlin.com>
---
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 8aff9ca1f222..400c4c2e434d 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;
--
2.47.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 5/6] of: Add #address-cells/#size-cells in the device-tree root empty node
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
` (3 preceding siblings ...)
2024-12-02 13:15 ` [PATCH v4 4/6] PCI: of_property: Constify parameter in of_pci_get_addr_flags() Herve Codina
@ 2024-12-02 13:15 ` Herve Codina
2024-12-02 15:48 ` Rob Herring
2024-12-02 13:15 ` [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node Herve Codina
5 siblings, 1 reply; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
On systems where ACPI is enabled or when a device-tree is not passed to
the kernel by the bootloader, a device-tree root empty node is created.
This device-tree root empty node does not have the #address-cells and
the #size-cells properties
This leads to the use of the default address cells and size cells values
which are defined in the code to 1 for the address cells value and 1 for
the size cells value.
According to the devicetree specification and the OpenFirmware standard
(IEEE 1275-1994) the default value for #address-cells should be 2.
Also, according to the devicetree specification, the #address-cells and
the #size-cells are required properties in the root node.
The device tree compiler already uses 2 as default value for address
cells and 1 for size cells. The powerpc PROM code also uses 2 as default
value for address cells and 1 for size cells. Modern implementation
should have the #address-cells and the #size-cells properties set and
should not rely on default values.
On x86, this root empty node is used and the code default values are
used.
In preparation of the support for device-tree overlay on PCI devices
feature on x86 (i.e. the creation of the PCI root bus device-tree node),
the default value for #address-cells needs to be updated. Indeed, on
x86_64, addresses are on 64bits and the upper part of an address is
needed for correct address translations. On x86_32 having the default
value updated does not lead to issues while the upper part of a 64-bit
value is zero.
Changing the default value for all architectures may break device-tree
compatibility. Indeed, existing dts file without the #address-cells
property set in the root node will not be compatible with this
modification.
Instead of updating default values, add both required #address-cells
and #size-cells properties in the device-tree empty node.
Use 2 for both properties value in order to fully support 64-bit
addresses and sizes on systems using this empty root node.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
drivers/of/empty_root.dts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/of/empty_root.dts b/drivers/of/empty_root.dts
index cf9e97a60f48..cbe169ba3db5 100644
--- a/drivers/of/empty_root.dts
+++ b/drivers/of/empty_root.dts
@@ -2,5 +2,12 @@
/dts-v1/;
/ {
-
+ /*
+ * #address-cells/#size-cells are required properties at root node.
+ * Use 2 cells for both address cells and size cells in order to fully
+ * support 64-bit addresses and sizes on systems using this empty root
+ * node.
+ */
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
};
--
2.47.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
` (4 preceding siblings ...)
2024-12-02 13:15 ` [PATCH v4 5/6] of: Add #address-cells/#size-cells in the device-tree root empty node Herve Codina
@ 2024-12-02 13:15 ` Herve Codina
2024-12-04 21:48 ` Bjorn Helgaas
5 siblings, 1 reply; 13+ messages in thread
From: Herve Codina @ 2024-12-02 13:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou
Cc: linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni, Herve Codina
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 do 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 <herve.codina@bootlin.com>
---
drivers/pci/of.c | 94 ++++++++++++++++++++++++++++++++++-
drivers/pci/of_property.c | 102 ++++++++++++++++++++++++++++++++++++++
drivers/pci/pci.h | 6 +++
drivers/pci/probe.c | 2 +
drivers/pci/remove.c | 2 +
5 files changed, 205 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 3cca33105b85..a63799848aac 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -726,7 +726,99 @@ 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) {
+ pr_err("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 */
+ device_add_of_node(&bridge->dev, np);
+ device_add_of_node(&bridge->bus->dev, np);
+
+ kfree(name);
+
+ return;
+
+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 400c4c2e434d..b03baff651ee 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 2e40fc63ba31..0cdb2b3daea8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -871,9 +871,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 2e81ab0f5a25..629287f6b3d9 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1051,6 +1051,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);
}
--
2.47.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v4 5/6] of: Add #address-cells/#size-cells in the device-tree root empty node
2024-12-02 13:15 ` [PATCH v4 5/6] of: Add #address-cells/#size-cells in the device-tree root empty node Herve Codina
@ 2024-12-02 15:48 ` Rob Herring
0 siblings, 0 replies; 13+ messages in thread
From: Rob Herring @ 2024-12-02 15:48 UTC (permalink / raw)
To: Herve Codina
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Saravana Kannan,
Bjorn Helgaas, Lizhi Hou, linux-kernel, devicetree, linux-pci,
Allan Nielsen, Horatiu Vultur, Steen Hegelund, Thomas Petazzoni
On Mon, Dec 02, 2024 at 02:15:17PM +0100, Herve Codina wrote:
> On systems where ACPI is enabled or when a device-tree is not passed to
> the kernel by the bootloader, a device-tree root empty node is created.
> This device-tree root empty node does not have the #address-cells and
> the #size-cells properties
>
> This leads to the use of the default address cells and size cells values
> which are defined in the code to 1 for the address cells value and 1 for
> the size cells value.
>
> According to the devicetree specification and the OpenFirmware standard
> (IEEE 1275-1994) the default value for #address-cells should be 2.
>
> Also, according to the devicetree specification, the #address-cells and
> the #size-cells are required properties in the root node.
>
> The device tree compiler already uses 2 as default value for address
> cells and 1 for size cells. The powerpc PROM code also uses 2 as default
> value for address cells and 1 for size cells. Modern implementation
> should have the #address-cells and the #size-cells properties set and
> should not rely on default values.
>
> On x86, this root empty node is used and the code default values are
> used.
>
> In preparation of the support for device-tree overlay on PCI devices
> feature on x86 (i.e. the creation of the PCI root bus device-tree node),
> the default value for #address-cells needs to be updated. Indeed, on
> x86_64, addresses are on 64bits and the upper part of an address is
> needed for correct address translations. On x86_32 having the default
> value updated does not lead to issues while the upper part of a 64-bit
> value is zero.
>
> Changing the default value for all architectures may break device-tree
> compatibility. Indeed, existing dts file without the #address-cells
> property set in the root node will not be compatible with this
> modification.
>
> Instead of updating default values, add both required #address-cells
> and #size-cells properties in the device-tree empty node.
>
> Use 2 for both properties value in order to fully support 64-bit
> addresses and sizes on systems using this empty root node.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
> drivers/of/empty_root.dts | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
This also fixes unittest hitting a warning added for 6.13. So
I've applied this patch as a fix.
Rob
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node()
2024-12-02 13:15 ` [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node() Herve Codina
@ 2024-12-04 21:38 ` Bjorn Helgaas
2024-12-05 7:00 ` Greg Kroah-Hartman
0 siblings, 1 reply; 13+ messages in thread
From: Bjorn Helgaas @ 2024-12-04 21:38 UTC (permalink / raw)
To: Herve Codina, Greg Kroah-Hartman, Rafael J. Wysocki
Cc: Rob Herring, Saravana Kannan, Bjorn Helgaas, Lizhi Hou,
linux-kernel, devicetree, linux-pci, Allan Nielsen,
Horatiu Vultur, Steen Hegelund, Thomas Petazzoni
[cc->to Greg, Rafael]
On Mon, Dec 02, 2024 at 02:15:13PM +0100, Herve Codina wrote:
> 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 <herve.codina@bootlin.com>
> ---
> drivers/base/core.c | 52 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/device.h | 2 ++
I suppose this series would go via the PCI tree since the bulk of the
changes are there. If so, I would look for an ack from the driver
core folks (Greg, Rafael).
> 2 files changed, 54 insertions(+)
>
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 8b056306f04e..3953c5ab7316 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -5216,6 +5216,58 @@ 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
> + */
> +void device_add_of_node(struct device *dev, struct device_node *of_node)
> +{
> + if (!of_node)
> + return;
> +
> + dev = get_device(dev);
> + if (!dev)
> + return;
> +
> + if (WARN(dev->of_node, "%s: Cannot replace node %pOF with %pOF\n",
> + dev_name(dev), dev->of_node, of_node))
> + goto end;
> +
> + dev->of_node = of_node_get(of_node);
> +
> + if (!dev->fwnode)
> + dev->fwnode = of_fwnode_handle(of_node);
> +
> +end:
> + put_device(dev);
> +}
> +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 667cb6db9019..ef4c0f3c41cd 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -1149,6 +1149,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);
> +void 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)
> --
> 2.47.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node
2024-12-02 13:15 ` [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node Herve Codina
@ 2024-12-04 21:48 ` Bjorn Helgaas
2024-12-05 7:37 ` Herve Codina
0 siblings, 1 reply; 13+ messages in thread
From: Bjorn Helgaas @ 2024-12-04 21:48 UTC (permalink / raw)
To: Herve Codina
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou, linux-kernel,
devicetree, linux-pci, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
On Mon, Dec 02, 2024 at 02:15:18PM +0100, Herve Codina wrote:
> 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 do 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.
s/do not exist/does not exist/
> +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) {
> + pr_err("PCI host bridge of_node already set");
Can we use dev_err() here?
Bjorn
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node()
2024-12-04 21:38 ` Bjorn Helgaas
@ 2024-12-05 7:00 ` Greg Kroah-Hartman
2024-12-05 7:33 ` Herve Codina
0 siblings, 1 reply; 13+ messages in thread
From: Greg Kroah-Hartman @ 2024-12-05 7:00 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Herve Codina, Rafael J. Wysocki, Rob Herring, Saravana Kannan,
Bjorn Helgaas, Lizhi Hou, linux-kernel, devicetree, linux-pci,
Allan Nielsen, Horatiu Vultur, Steen Hegelund, Thomas Petazzoni
On Wed, Dec 04, 2024 at 03:38:25PM -0600, Bjorn Helgaas wrote:
> [cc->to Greg, Rafael]
>
> On Mon, Dec 02, 2024 at 02:15:13PM +0100, Herve Codina wrote:
> > 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 <herve.codina@bootlin.com>
> > ---
> > drivers/base/core.c | 52 ++++++++++++++++++++++++++++++++++++++++++
> > include/linux/device.h | 2 ++
>
> I suppose this series would go via the PCI tree since the bulk of the
> changes are there. If so, I would look for an ack from the driver
> core folks (Greg, Rafael).
>
> > 2 files changed, 54 insertions(+)
> >
> > diff --git a/drivers/base/core.c b/drivers/base/core.c
> > index 8b056306f04e..3953c5ab7316 100644
> > --- a/drivers/base/core.c
> > +++ b/drivers/base/core.c
> > @@ -5216,6 +5216,58 @@ 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
> > + */
> > +void device_add_of_node(struct device *dev, struct device_node *of_node)
> > +{
> > + if (!of_node)
> > + return;
> > +
> > + dev = get_device(dev);
> > + if (!dev)
> > + return;
> > +
> > + if (WARN(dev->of_node, "%s: Cannot replace node %pOF with %pOF\n",
> > + dev_name(dev), dev->of_node, of_node))
> > + goto end;
Please do not reboot machines that have panic-on-warn for something that
you can properly handle and recover from (like this.) Just print out a
message and continue on, or better yet, return an error if this didn't
work properly.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node()
2024-12-05 7:00 ` Greg Kroah-Hartman
@ 2024-12-05 7:33 ` Herve Codina
0 siblings, 0 replies; 13+ messages in thread
From: Herve Codina @ 2024-12-05 7:33 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Bjorn Helgaas, Rafael J. Wysocki, Rob Herring, Saravana Kannan,
Bjorn Helgaas, Lizhi Hou, linux-kernel, devicetree, linux-pci,
Allan Nielsen, Horatiu Vultur, Steen Hegelund, Thomas Petazzoni
Hi Greg,
On Thu, 5 Dec 2024 08:00:44 +0100
Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
> On Wed, Dec 04, 2024 at 03:38:25PM -0600, Bjorn Helgaas wrote:
> > [cc->to Greg, Rafael]
> >
> > On Mon, Dec 02, 2024 at 02:15:13PM +0100, Herve Codina wrote:
> > > 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 <herve.codina@bootlin.com>
> > > ---
> > > drivers/base/core.c | 52 ++++++++++++++++++++++++++++++++++++++++++
> > > include/linux/device.h | 2 ++
> >
> > I suppose this series would go via the PCI tree since the bulk of the
> > changes are there. If so, I would look for an ack from the driver
> > core folks (Greg, Rafael).
> >
> > > 2 files changed, 54 insertions(+)
> > >
> > > diff --git a/drivers/base/core.c b/drivers/base/core.c
> > > index 8b056306f04e..3953c5ab7316 100644
> > > --- a/drivers/base/core.c
> > > +++ b/drivers/base/core.c
> > > @@ -5216,6 +5216,58 @@ 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
> > > + */
> > > +void device_add_of_node(struct device *dev, struct device_node *of_node)
> > > +{
> > > + if (!of_node)
> > > + return;
> > > +
> > > + dev = get_device(dev);
> > > + if (!dev)
> > > + return;
> > > +
> > > + if (WARN(dev->of_node, "%s: Cannot replace node %pOF with %pOF\n",
> > > + dev_name(dev), dev->of_node, of_node))
> > > + goto end;
>
> Please do not reboot machines that have panic-on-warn for something that
> you can properly handle and recover from (like this.) Just print out a
> message and continue on, or better yet, return an error if this didn't
> work properly.
>
I will change to dev_warn() in the next iteration.
Thanks for pointing this.
Best regards,
Hervé
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node
2024-12-04 21:48 ` Bjorn Helgaas
@ 2024-12-05 7:37 ` Herve Codina
0 siblings, 0 replies; 13+ messages in thread
From: Herve Codina @ 2024-12-05 7:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Lizhi Hou, linux-kernel,
devicetree, linux-pci, Allan Nielsen, Horatiu Vultur,
Steen Hegelund, Thomas Petazzoni
Hi Bjorn,
On Wed, 4 Dec 2024 15:48:52 -0600
Bjorn Helgaas <helgaas@kernel.org> wrote:
> On Mon, Dec 02, 2024 at 02:15:18PM +0100, Herve Codina wrote:
> > 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 do 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.
>
> s/do not exist/does not exist/
Will be fix in the next iteration.
>
> > +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) {
> > + pr_err("PCI host bridge of_node already set");
>
> Can we use dev_err() here?
Yes indeed.
Will be change in the next iteration.
Best regards,
Hervé
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-12-05 7:38 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-02 13:15 [PATCH v4 0/6] Add support for the PCI host bridge device-tree node creation Herve Codina
2024-12-02 13:15 ` [PATCH v4 1/6] driver core: Introduce device_{add,remove}_of_node() Herve Codina
2024-12-04 21:38 ` Bjorn Helgaas
2024-12-05 7:00 ` Greg Kroah-Hartman
2024-12-05 7:33 ` Herve Codina
2024-12-02 13:15 ` [PATCH v4 2/6] PCI: of: Use device_{add,remove}_of_node() to attach of_node to existing device Herve Codina
2024-12-02 13:15 ` [PATCH v4 3/6] PCI: of_property: Add support for NULL pdev in of_pci_set_address() Herve Codina
2024-12-02 13:15 ` [PATCH v4 4/6] PCI: of_property: Constify parameter in of_pci_get_addr_flags() Herve Codina
2024-12-02 13:15 ` [PATCH v4 5/6] of: Add #address-cells/#size-cells in the device-tree root empty node Herve Codina
2024-12-02 15:48 ` Rob Herring
2024-12-02 13:15 ` [PATCH v4 6/6] PCI: of: Create device-tree PCI host bridge node Herve Codina
2024-12-04 21:48 ` Bjorn Helgaas
2024-12-05 7:37 ` Herve Codina
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).