[Skiboot] [PATCH v4] PCI: create optional loc-code platform callback
Klaus Heinrich Kiwi
klaus at linux.vnet.ibm.com
Tue Feb 18 22:37:30 AEDT 2020
Some platforms (mostly OpenPower-based) will favor a short,
slot-label-based string for the "ibm,loc-code" DT property. Other
platforms such as ZZ/FSP-based platforms will prefer the fully-qualified
slot-location-code for it.
This patches creates a new operation on the platform struct, allowing
for an optional callback to create the "ibm,loc-code" property in a
platform-specific way. If the callback is not defined, use the
cleaned-up default that was in use so far.
Signed-off-by: Klaus Heinrich Kiwi <klaus at linux.vnet.ibm.com>
---
core/pci.c | 42 ++++----------------
include/platform.h | 8 ++++
platforms/ibm-fsp/firenze-pci.c | 70 +++++++++++++++++++++++++++++++++
platforms/ibm-fsp/firenze.c | 1 +
platforms/ibm-fsp/ibm-fsp.h | 2 +
platforms/ibm-fsp/zz.c | 1 +
6 files changed, 89 insertions(+), 35 deletions(-)
diff --git a/core/pci.c b/core/pci.c
index 8b52fc10..d211207b 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -1383,17 +1383,13 @@ void pci_std_swizzle_irq_map(struct dt_node *np,
free(map);
}
-static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
+static void pci_add_loc_code(struct dt_node *np)
{
struct dt_node *p = np->parent;
const char *blcode = NULL;
- char *lcode;
- uint32_t class_code;
- uint8_t class, sub;
- uint8_t pos, len;
while (p) {
- /* if we have a slot label (i.e. openpower) use that */
+ /* prefer slot-label by default */
blcode = dt_prop_get_def(p, "ibm,slot-label", NULL);
if (blcode)
break;
@@ -1424,34 +1420,7 @@ static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
if (!blcode)
return;
- /* ethernet devices get port codes */
- class_code = dt_prop_get_u32(np, "class-code");
- class = class_code >> 16;
- sub = (class_code >> 8) & 0xff;
-
- /* XXX Don't do that on openpower for now, we will need to sort things
- * out later, otherwise the mezzanine slot on Habanero gets weird results
- */
- if (class == 0x02 && sub == 0x00 && !platform.bmc) {
- /* There's usually several spaces at the end of the property.
- Test for, but don't rely on, that being the case */
- len = strlen(blcode);
- for (pos = 0; pos < len; pos++)
- if (blcode[pos] == ' ') break;
- if (pos + 3 < len)
- lcode = strdup(blcode);
- else {
- lcode = malloc(pos + 3);
- memcpy(lcode, blcode, len);
- }
- lcode[pos++] = '-';
- lcode[pos++] = 'T';
- lcode[pos++] = (char)PCI_FUNC(pd->bdfn) + '1';
- lcode[pos++] = '\0';
- dt_add_property_string(np, "ibm,loc-code", lcode);
- free(lcode);
- } else
- dt_add_property_string(np, "ibm,loc-code", blcode);
+ dt_add_property_string(np, "ibm,loc-code", blcode);
}
static void pci_print_summary_line(struct phb *phb, struct pci_device *pd,
@@ -1595,7 +1564,10 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
phb->base_loc_code);
/* Make up location code */
- pci_add_loc_code(np, pd);
+ if (platform.pci_add_loc_code)
+ platform.pci_add_loc_code(np, pd);
+ else
+ pci_add_loc_code(np);
/* XXX FIXME: We don't look for BARs, we only put the config space
* entry in the "reg" property. That's enough for Linux and we might
diff --git a/include/platform.h b/include/platform.h
index 6909a6a4..671878b9 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -185,6 +185,14 @@ struct platform {
void (*pci_get_slot_info)(struct phb *phb,
struct pci_device *pd);
+ /*
+ * Called for each device during pci_add_device_nodes() descend
+ * to create the device tree, in order to get the correct per-platform
+ * preference for the ibm,loc-code property
+ */
+ void (*pci_add_loc_code)(struct dt_node *np,
+ struct pci_device *pd);
+
/*
* Called after PCI probe is complete and before inventory is
* displayed in console. This can either run platform fixups or
diff --git a/platforms/ibm-fsp/firenze-pci.c b/platforms/ibm-fsp/firenze-pci.c
index 6d5aab1e..efbe5525 100644
--- a/platforms/ibm-fsp/firenze-pci.c
+++ b/platforms/ibm-fsp/firenze-pci.c
@@ -972,3 +972,73 @@ void firenze_pci_get_slot_info(struct phb *phb, struct pci_device *pd)
firenze_pci_slot_init(slot);
}
}
+
+void firenze_pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
+{
+ struct dt_node *p;
+ const char *blcode = NULL;
+ char *lcode;
+ uint32_t class_code;
+ uint8_t class,sub;
+ uint8_t pos, len;
+
+
+ /*
+ * prefer fully-qualified slot-location-code, walk-up parent tree
+ * to find one
+ */
+ for (p = np->parent; p; p = np->parent) {
+ blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
+ if (blcode)
+ break;
+ }
+
+ /* try the node itself if none is found */
+ if (!blcode)
+ blcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
+
+ if (!blcode) {
+ /* still not found, fall back to ibm,loc-code */
+
+ for (p = np->parent; p; p = p->parent) {
+ blcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
+ if (blcode)
+ break;
+ }
+ }
+
+ if (!blcode) {
+ prlog(PR_ERR,
+ "No suitable location code to add for device PHB#%04x:%02x:%02x.%x\n",
+ pd->phb->opal_id, PCI_BUS_NUM(pd->bdfn),
+ PCI_DEV(pd->bdfn), PCI_FUNC(pd->bdfn));
+ return;
+ }
+
+ /* ethernet devices get port codes */
+ class_code = dt_prop_get_u32(np, "class-code");
+ class = class_code >> 16;
+ sub = (class_code >> 8) & 0xff;
+
+ if (class == 0x02 && sub == 0x00) {
+ /* There's usually several spaces at the end of the property.
+ Test for, but don't rely on, that being the case */
+ len = strlen(blcode);
+ for (pos = 0; pos < len; pos++)
+ if (blcode[pos] == ' ') break;
+ if (pos + 3 < len)
+ lcode = strdup(blcode);
+ else {
+ lcode = malloc(pos + 3);
+ memcpy(lcode, blcode, len);
+ }
+ lcode[pos++] = '-';
+ lcode[pos++] = 'T';
+ lcode[pos++] = (char)PCI_FUNC(pd->bdfn) + '1';
+ lcode[pos++] = '\0';
+ dt_add_property_string(np, "ibm,loc-code", lcode);
+ free(lcode);
+ } else {
+ dt_add_property_string(np, "ibm,loc-code", blcode);
+ }
+}
diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c
index 26977450..f4389049 100644
--- a/platforms/ibm-fsp/firenze.c
+++ b/platforms/ibm-fsp/firenze.c
@@ -206,6 +206,7 @@ DECLARE_PLATFORM(firenze) = {
.cec_reboot = ibm_fsp_cec_reboot,
.pci_setup_phb = firenze_pci_setup_phb,
.pci_get_slot_info = firenze_pci_get_slot_info,
+ .pci_add_loc_code = firenze_pci_add_loc_code,
.pci_probe_complete = firenze_pci_send_inventory,
.nvram_info = fsp_nvram_info,
.nvram_start_read = fsp_nvram_start_read,
diff --git a/platforms/ibm-fsp/ibm-fsp.h b/platforms/ibm-fsp/ibm-fsp.h
index 16af68f8..145ac0ad 100644
--- a/platforms/ibm-fsp/ibm-fsp.h
+++ b/platforms/ibm-fsp/ibm-fsp.h
@@ -29,6 +29,8 @@ extern void firenze_pci_setup_phb(struct phb *phb,
unsigned int index);
extern void firenze_pci_get_slot_info(struct phb *phb,
struct pci_device *pd);
+extern void firenze_pci_add_loc_code(struct dt_node *np,
+ struct pci_device *pd);
/* VPD support */
void vpd_iohub_load(struct dt_node *hub_node);
diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c
index f4aa85fa..14a54d64 100644
--- a/platforms/ibm-fsp/zz.c
+++ b/platforms/ibm-fsp/zz.c
@@ -184,6 +184,7 @@ DECLARE_PLATFORM(zz) = {
.cec_reboot = ibm_fsp_cec_reboot,
.pci_setup_phb = firenze_pci_setup_phb,
.pci_get_slot_info = firenze_pci_get_slot_info,
+ .pci_add_loc_code = firenze_pci_add_loc_code,
.pci_probe_complete = firenze_pci_send_inventory,
.nvram_info = fsp_nvram_info,
.nvram_start_read = fsp_nvram_start_read,
--
2.17.1
More information about the Skiboot
mailing list