|
@@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)
|
|
subsys_initcall(pcibios_init);
|
|
subsys_initcall(pcibios_init);
|
|
|
|
|
|
#ifdef CONFIG_SYSFS
|
|
#ifdef CONFIG_SYSFS
|
|
|
|
+
|
|
|
|
+#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */
|
|
|
|
+
|
|
|
|
+static void pcie_bus_slot_names(struct pci_bus *pbus)
|
|
|
|
+{
|
|
|
|
+ struct pci_dev *pdev;
|
|
|
|
+ struct pci_bus *bus;
|
|
|
|
+
|
|
|
|
+ list_for_each_entry(pdev, &pbus->devices, bus_list) {
|
|
|
|
+ char name[SLOT_NAME_SIZE];
|
|
|
|
+ struct pci_slot *pci_slot;
|
|
|
|
+ const u32 *slot_num;
|
|
|
|
+ int len;
|
|
|
|
+
|
|
|
|
+ slot_num = of_get_property(pdev->dev.of_node,
|
|
|
|
+ "physical-slot#", &len);
|
|
|
|
+
|
|
|
|
+ if (slot_num == NULL || len != 4)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ snprintf(name, sizeof(name), "%u", slot_num[0]);
|
|
|
|
+ pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL);
|
|
|
|
+
|
|
|
|
+ if (IS_ERR(pci_slot))
|
|
|
|
+ pr_err("PCI: pci_create_slot returned %ld.\n",
|
|
|
|
+ PTR_ERR(pci_slot));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ list_for_each_entry(bus, &pbus->children, node)
|
|
|
|
+ pcie_bus_slot_names(bus);
|
|
|
|
+}
|
|
|
|
+
|
|
static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
|
|
static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
|
|
{
|
|
{
|
|
const struct pci_slot_names {
|
|
const struct pci_slot_names {
|
|
@@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void)
|
|
|
|
|
|
while ((pbus = pci_find_next_bus(pbus)) != NULL) {
|
|
while ((pbus = pci_find_next_bus(pbus)) != NULL) {
|
|
struct device_node *node;
|
|
struct device_node *node;
|
|
|
|
+ struct pci_dev *pdev;
|
|
|
|
+
|
|
|
|
+ pdev = list_first_entry(&pbus->devices, struct pci_dev,
|
|
|
|
+ bus_list);
|
|
|
|
|
|
- if (pbus->self) {
|
|
|
|
- /* PCI->PCI bridge */
|
|
|
|
- node = pbus->self->dev.of_node;
|
|
|
|
|
|
+ if (pdev && pci_is_pcie(pdev)) {
|
|
|
|
+ pcie_bus_slot_names(pbus);
|
|
} else {
|
|
} else {
|
|
- struct pci_pbm_info *pbm = pbus->sysdata;
|
|
|
|
|
|
|
|
- /* Host PCI controller */
|
|
|
|
- node = pbm->op->dev.of_node;
|
|
|
|
- }
|
|
|
|
|
|
+ if (pbus->self) {
|
|
|
|
+
|
|
|
|
+ /* PCI->PCI bridge */
|
|
|
|
+ node = pbus->self->dev.of_node;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ struct pci_pbm_info *pbm = pbus->sysdata;
|
|
|
|
|
|
- pci_bus_slot_names(node, pbus);
|
|
|
|
|
|
+ /* Host PCI controller */
|
|
|
|
+ node = pbm->op->dev.of_node;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pci_bus_slot_names(node, pbus);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|