Adds the path of the device-tree node of a PCI device to the lspci -v
output, like so:
0021:00:00.0 PCI bridge: IBM Device 03dc (prog-if 00 [Normal decode])
DT Node: /sys/firmware/devicetree/base/pciex@
3fffe41100000/pci@0
This is added as a generic property to struct pci_device and populated
by the sysfs backend. Other platforms may find it useful though.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
pci_mfree(d->module_alias);
pci_mfree(d->label);
pci_mfree(d->phy_slot);
+ pci_mfree(d->dt_node);
pci_mfree(d);
}
char *phy_slot; /* Physical slot */
char *module_alias; /* Linux kernel module alias */
char *label; /* Device name as exported by BIOS */
+ char *dt_node; /* Path to the device-tree node for this device */
int numa_node; /* NUMA node */
pciaddr_t flags[6]; /* PCI_IORESOURCE_* flags for regions */
pciaddr_t rom_flags; /* PCI_IORESOURCE_* flags for expansion ROM */
#define PCI_FILL_LABEL 0x0400
#define PCI_FILL_NUMA_NODE 0x0800
#define PCI_FILL_IO_FLAGS 0x1000
+#define PCI_FILL_DT_NODE 0x2000
#define PCI_FILL_RESCAN 0x00010000
void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI;
return 1;
}
+static char *
+sysfs_deref_link(struct pci_dev *d, char *link_name)
+{
+ char path[2*OBJNAMELEN], rel_path[OBJNAMELEN];
+
+ sysfs_obj_name(d, link_name, path);
+ memset(rel_path, 0, sizeof(rel_path));
+
+ if (readlink(path, rel_path, sizeof(rel_path)) < 0)
+ return NULL;
+
+ sysfs_obj_name(d, "", path);
+ strcat(path, rel_path);
+
+ return canonicalize_file_name(path);
+}
+
static int
sysfs_get_value(struct pci_dev *d, char *object, int mandatory)
{
if ((flags & PCI_FILL_NUMA_NODE) && !(d->known_fields & PCI_FILL_NUMA_NODE))
d->numa_node = sysfs_get_value(d, "numa_node", 0);
+ if ((flags & PCI_FILL_DT_NODE) && !(d->known_fields & PCI_FILL_DT_NODE))
+ d->dt_node = sysfs_deref_link(d, "of_node");
+
return pci_generic_fill_info(d, flags);
}
show_terse(d);
pci_fill_info(p, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES |
- PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE);
+ PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE);
irq = p->irq;
switch (htype)
if (verbose > 1)
{
+ if (p->dt_node)
+ printf("\tDT Node: %s\n", p->dt_node);
printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n",
FLAG(cmd, PCI_COMMAND_IO),
FLAG(cmd, PCI_COMMAND_MEMORY),
}
else
{
+ if (p->dt_node)
+ printf("\tDT Node: %s\n", p->dt_node);
printf("\tFlags: ");
if (cmd & PCI_COMMAND_MASTER)
printf("bus master, ");
if (verbose)
{
- pci_fill_info(p, PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE);
+ pci_fill_info(p, PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE);
printf((opt_machine >= 2) ? "Slot:\t" : "Device:\t");
show_slot_name(d);
putchar('\n');
show_kernel_machine(d);
if (p->numa_node != -1)
printf("NUMANode:\t%d\n", p->numa_node);
+ if (p->dt_node)
+ printf("DTNode:\t%s\n", p->dt_node);
}
else
{