aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Snowberg <eric.snowberg@oracle.com>2015-05-27 11:59:19 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-01 01:14:40 -0400
commitf0c1a1173773a56d500f1814893e63f97580f76a (patch)
treef1ff5165d3a6e6873bd0a74fcfdba1b523fdeeab
parent8642ad1c7ba43b1c48eb39a863e975f3f8f96168 (diff)
sparc64: pci slots information is not populated in sysfs
Add PCI slot numbers within sysfs for PCIe hardware. Larger PCIe systems with nested PCI bridges and slots further down on these bridges were not being populated within sysfs. This will add ACPI style PCI slot numbers for these systems since the OF 'slot-names' information is not available on all PCIe platforms. Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com> Reviewed-by: Bob Picco <bob.picco@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/kernel/pci.c59
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)
1002subsys_initcall(pcibios_init); 1002subsys_initcall(pcibios_init);
1003 1003
1004#ifdef CONFIG_SYSFS 1004#ifdef CONFIG_SYSFS
1005
1006#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */
1007
1008static void pcie_bus_slot_names(struct pci_bus *pbus)
1009{
1010 struct pci_dev *pdev;
1011 struct pci_bus *bus;
1012
1013 list_for_each_entry(pdev, &pbus->devices, bus_list) {
1014 char name[SLOT_NAME_SIZE];
1015 struct pci_slot *pci_slot;
1016 const u32 *slot_num;
1017 int len;
1018
1019 slot_num = of_get_property(pdev->dev.of_node,
1020 "physical-slot#", &len);
1021
1022 if (slot_num == NULL || len != 4)
1023 continue;
1024
1025 snprintf(name, sizeof(name), "%u", slot_num[0]);
1026 pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL);
1027
1028 if (IS_ERR(pci_slot))
1029 pr_err("PCI: pci_create_slot returned %ld.\n",
1030 PTR_ERR(pci_slot));
1031 }
1032
1033 list_for_each_entry(bus, &pbus->children, node)
1034 pcie_bus_slot_names(bus);
1035}
1036
1005static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) 1037static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
1006{ 1038{
1007 const struct pci_slot_names { 1039 const struct pci_slot_names {
@@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void)
1053 1085
1054 while ((pbus = pci_find_next_bus(pbus)) != NULL) { 1086 while ((pbus = pci_find_next_bus(pbus)) != NULL) {
1055 struct device_node *node; 1087 struct device_node *node;
1088 struct pci_dev *pdev;
1089
1090 pdev = list_first_entry(&pbus->devices, struct pci_dev,
1091 bus_list);
1056 1092
1057 if (pbus->self) { 1093 if (pdev && pci_is_pcie(pdev)) {
1058 /* PCI->PCI bridge */ 1094 pcie_bus_slot_names(pbus);
1059 node = pbus->self->dev.of_node;
1060 } else { 1095 } else {
1061 struct pci_pbm_info *pbm = pbus->sysdata;
1062 1096
1063 /* Host PCI controller */ 1097 if (pbus->self) {
1064 node = pbm->op->dev.of_node; 1098
1065 } 1099 /* PCI->PCI bridge */
1100 node = pbus->self->dev.of_node;
1101
1102 } else {
1103 struct pci_pbm_info *pbm = pbus->sysdata;
1066 1104
1067 pci_bus_slot_names(node, pbus); 1105 /* Host PCI controller */
1106 node = pbm->op->dev.of_node;
1107 }
1108
1109 pci_bus_slot_names(node, pbus);
1110 }
1068 } 1111 }
1069 1112
1070 return 0; 1113 return 0;