diff options
Diffstat (limited to 'arch/sparc/kernel/pci.c')
| -rw-r--r-- | arch/sparc/kernel/pci.c | 59 | 
1 files changed, 51 insertions, 8 deletions
| diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 6f7251fd2eab..c928bc64b4ba 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)  subsys_initcall(pcibios_init);  #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)  {  	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) {  		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 { -			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; |