[Skiboot] [PATCH 3/4] PCI: Introduce phb_ops->phb_final_fixup()

Gavin Shan gwshan at linux.vnet.ibm.com
Tue Apr 26 11:56:53 AEST 2016


phb_ops->device_node_fixup() was introduced for NPU1 so that the
chip backend can bind the emulated NPU device with the GPU device
and fixes the device-tree node accordingly. There're couple of
issues as I can image:

   * In pci_fixup_nodes(), one PHB has only one level of device
     depth in the hierarchy tree. It's true for NPU PHBs, but
     false for other PHBs. That indicates the function can be
     called for NPU PHBs.
   * The callback name indicates the specific work to be done
     there. That doesn't make sense. We need another name without
     indicating the specific work to do. It will give the backend
     on chip level more freedom. Similarly, the callback is called
     on basis of PCI device. It's hard for backend to manuplate
     the PHB. More freedom the backend will get with more bold
     granularity.

This fixes above issues by replacing phb_ops->device_node_fixup()
with phb_ops->phb_final_fixup(). More freedom will be received in
the backends.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pci.c    | 19 ++++---------------
 hw/npu.c      | 15 ++++++++++++---
 include/pci.h |  7 ++-----
 3 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/core/pci.c b/core/pci.c
index 66c2470..9b238d0 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -1450,17 +1450,6 @@ static void pci_add_nodes(struct phb *phb)
 		pci_add_one_node(phb, pd, phb->dt_node, lstate, 0);
 }
 
-static void pci_fixup_nodes(struct phb *phb)
-{
-	struct pci_device *pd;
-
-	if (!phb->ops->device_node_fixup)
-		return;
-
-	list_for_each(&phb->devices, pd, link)
-		phb->ops->device_node_fixup(phb, pd);
-}
-
 static void __pci_reset(struct list_head *list)
 {
 	struct pci_device *pd;
@@ -1542,12 +1531,12 @@ void pci_init_slots(void)
 		pci_add_nodes(phbs[i]);
 	}
 
-	/* Do device node fixups now that all the devices have been
-	 * added to the device tree. */
+	/* PHB final fixup */
 	for (i = 0; i < ARRAY_SIZE(phbs); i++) {
-		if (!phbs[i])
+		if (!phbs[i] || !phbs[i]->ops || !phbs[i]->ops->phb_final_fixup)
 			continue;
-		pci_fixup_nodes(phbs[i]);
+
+		phbs[i]->ops->phb_final_fixup(phbs[i]);
 	}
 }
 
diff --git a/hw/npu.c b/hw/npu.c
index 14d49a7..3e419c4 100644
--- a/hw/npu.c
+++ b/hw/npu.c
@@ -585,7 +585,9 @@ static void npu_append_pci_phandle(struct dt_node *dn, u32 phandle)
 	unlock(&pci_npu_phandle_lock);
 }
 
-static void npu_dn_fixup(struct phb *phb, struct pci_device *pd)
+static int npu_dn_fixup(struct phb *phb,
+			struct pci_device *pd,
+			void *data __unused)
 {
 	struct npu *p = phb_to_npu(phb);
 	struct npu_dev *dev;
@@ -594,7 +596,7 @@ static void npu_dn_fixup(struct phb *phb, struct pci_device *pd)
 	assert(dev);
 
 	if (dev->phb || dev->pd)
-		return;
+		return 0;
 
 	/* Bind the emulated PCI device with the real one, which can't
 	 * be done until the PCI devices are populated. Once the real
@@ -610,6 +612,13 @@ static void npu_dn_fixup(struct phb *phb, struct pci_device *pd)
 
 		dt_add_property_cells(pd->dn, "ibm,gpu", dev->pd->dn->phandle);
 	}
+
+	return 0;
+}
+
+static void npu_phb_final_fixup(struct phb *phb)
+{
+	pci_walk_dev(phb, npu_dn_fixup, NULL);
 }
 
 static void npu_ioda_init(struct npu *p)
@@ -1095,7 +1104,7 @@ static const struct phb_ops npu_ops = {
 	.cfg_write32		= npu_dev_cfg_write32,
 	.choose_bus		= NULL,
 	.device_init		= NULL,
-	.device_node_fixup	= npu_dn_fixup,
+	.phb_final_fixup	= npu_phb_final_fixup,
 	.presence_detect	= NULL,
 	.ioda_reset		= npu_ioda_reset,
 	.papr_errinjct_reset	= NULL,
diff --git a/include/pci.h b/include/pci.h
index b9e6ac6..3541374 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -262,11 +262,8 @@ struct phb_ops {
 	 */
 	void (*device_init)(struct phb *phb, struct pci_device *device);
 
-	/*
-	 * Device node fixup is called when the PCI device node is being
-	 * populated
-	 */
-	void (*device_node_fixup)(struct phb *phb, struct pci_device *pd);
+	/* PHB final fixup is called after PCI probing is completed */
+	void (*phb_final_fixup)(struct phb *phb);
 
 	/*
 	 * EEH methods
-- 
2.1.0



More information about the Skiboot mailing list