|
@@ -1094,3 +1094,78 @@ static int __init pcibios_init(void)
|
|
|
return 0;
|
|
|
}
|
|
|
subsys_initcall(pcibios_init);
|
|
|
+
|
|
|
+#ifdef CONFIG_SYSFS
|
|
|
+static void __devinit pci_bus_slot_names(struct device_node *node,
|
|
|
+ struct pci_bus *bus)
|
|
|
+{
|
|
|
+ const struct pci_slot_names {
|
|
|
+ u32 slot_mask;
|
|
|
+ char names[0];
|
|
|
+ } *prop;
|
|
|
+ const char *sp;
|
|
|
+ int len, i;
|
|
|
+ u32 mask;
|
|
|
+
|
|
|
+ prop = of_get_property(node, "slot-names", &len);
|
|
|
+ if (!prop)
|
|
|
+ return;
|
|
|
+
|
|
|
+ mask = prop->slot_mask;
|
|
|
+ sp = prop->names;
|
|
|
+
|
|
|
+ if (ofpci_verbose)
|
|
|
+ printk("PCI: Making slots for [%s] mask[0x%02x]\n",
|
|
|
+ node->full_name, mask);
|
|
|
+
|
|
|
+ i = 0;
|
|
|
+ while (mask) {
|
|
|
+ struct pci_slot *pci_slot;
|
|
|
+ u32 this_bit = 1 << i;
|
|
|
+
|
|
|
+ if (!(mask & this_bit)) {
|
|
|
+ i++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ofpci_verbose)
|
|
|
+ printk("PCI: Making slot [%s]\n", sp);
|
|
|
+
|
|
|
+ pci_slot = pci_create_slot(bus, i, sp, NULL);
|
|
|
+ if (IS_ERR(pci_slot))
|
|
|
+ printk(KERN_ERR "PCI: pci_create_slot returned %ld\n",
|
|
|
+ PTR_ERR(pci_slot));
|
|
|
+
|
|
|
+ sp += strlen(sp) + 1;
|
|
|
+ mask &= ~this_bit;
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int __init of_pci_slot_init(void)
|
|
|
+{
|
|
|
+ struct pci_bus *pbus = NULL;
|
|
|
+
|
|
|
+ while ((pbus = pci_find_next_bus(pbus)) != NULL) {
|
|
|
+ struct device_node *node;
|
|
|
+
|
|
|
+ if (pbus->self) {
|
|
|
+ struct dev_archdata *sd = pbus->self->sysdata;
|
|
|
+
|
|
|
+ /* PCI->PCI bridge */
|
|
|
+ node = sd->prom_node;
|
|
|
+ } else {
|
|
|
+ struct pci_pbm_info *pbm = pbus->sysdata;
|
|
|
+
|
|
|
+ /* Host PCI controller */
|
|
|
+ node = pbm->op->node;
|
|
|
+ }
|
|
|
+
|
|
|
+ pci_bus_slot_names(node, pbus);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+module_init(of_pci_slot_init);
|
|
|
+#endif
|