diff options
-rw-r--r-- | core/pci.c | 42 | ||||
-rw-r--r-- | include/platform.h | 8 | ||||
-rw-r--r-- | platforms/ibm-fsp/firenze-pci.c | 70 | ||||
-rw-r--r-- | platforms/ibm-fsp/firenze.c | 1 | ||||
-rw-r--r-- | platforms/ibm-fsp/ibm-fsp.h | 2 | ||||
-rw-r--r-- | platforms/ibm-fsp/zz.c | 1 |
6 files changed, 89 insertions, 35 deletions
@@ -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 6909a6a..671878b 100644 --- a/include/platform.h +++ b/include/platform.h @@ -186,6 +186,14 @@ struct platform { 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 * can be used to send the inventory to a service processor. diff --git a/platforms/ibm-fsp/firenze-pci.c b/platforms/ibm-fsp/firenze-pci.c index 6d5aab1..efbe552 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 2697745..f438904 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 16af68f..145ac0a 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 f4aa85f..14a54d6 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, |