diff options
author | Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> | 2020-02-18 08:37:30 -0300 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2020-02-24 12:56:03 +1100 |
commit | ab1b05d29f5e9715a754a68bcb565e29cee0e48a (patch) | |
tree | 5296370f84bd26d792ec8cdf50b61c28ed538121 /platforms | |
parent | 59482b92af1b7cc1a75d39b64a956ef6ae08b538 (diff) | |
download | skiboot-ab1b05d29f5e9715a754a68bcb565e29cee0e48a.zip skiboot-ab1b05d29f5e9715a754a68bcb565e29cee0e48a.tar.gz skiboot-ab1b05d29f5e9715a754a68bcb565e29cee0e48a.tar.bz2 |
PCI: create optional loc-code platform callback
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@linux.vnet.ibm.com>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'platforms')
-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 |
4 files changed, 74 insertions, 0 deletions
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, |