]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/pci/hotplug/rpaphp_pci.c
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6-omap-h63xx.git] / drivers / pci / hotplug / rpaphp_pci.c
index f7c12d7dfcfc35bc164163672b60ef817bc23ff5..4b35097b3d9fba0201dca7e2bca9f6fa8eb07dd9 100644 (file)
@@ -154,8 +154,7 @@ exit:
 }
 
 /* Must be called before pci_bus_add_devices */
-static void 
-rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
+void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
 {
        struct pci_dev *dev;
 
@@ -184,6 +183,20 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
        }
 }
 
+static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
+{
+       struct pci_dev *dev;
+
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               eeh_add_device_late(dev);
+               if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+                       struct pci_bus *subbus = dev->subordinate;
+                       if (subbus)
+                               rpaphp_eeh_add_bus_device (subbus);
+               }
+       }
+}
+
 static int rpaphp_pci_config_bridge(struct pci_dev *dev)
 {
        u8 sec_busno;
@@ -217,6 +230,13 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
        return 0;
 }
 
+void rpaphp_init_new_devs(struct pci_bus *bus)
+{
+       rpaphp_fixup_new_pci_devices(bus, 0);
+       rpaphp_eeh_add_bus_device(bus);
+}
+EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
+
 /*****************************************************************************
  rpaphp_pci_config_slot() will  configure all devices under the
  given slot->dn and return the the first pci_dev.
@@ -233,36 +253,51 @@ rpaphp_pci_config_slot(struct pci_bus *bus)
        if (!dn || !dn->child)
                return NULL;
 
-       slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+       if (_machine == PLATFORM_PSERIES_LPAR) {
+               of_scan_bus(dn, bus);
+               if (list_empty(&bus->devices)) {
+                       err("%s: No new device found\n", __FUNCTION__);
+                       return NULL;
+               }
 
-       /* pci_scan_slot should find all children */
-       num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
-       if (num) {
-               rpaphp_fixup_new_pci_devices(bus, 1);
+               rpaphp_init_new_devs(bus);
                pci_bus_add_devices(bus);
-       }
-       if (list_empty(&bus->devices)) {
-               err("%s: No new device found\n", __FUNCTION__);
-               return NULL;
-       }
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
-                       rpaphp_pci_config_bridge(dev);
+               dev = list_entry(&bus->devices, struct pci_dev, bus_list);
+       } else {
+               slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+
+               /* pci_scan_slot should find all children */
+               num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+               if (num) {
+                       rpaphp_fixup_new_pci_devices(bus, 1);
+                       pci_bus_add_devices(bus);
+               }
+               if (list_empty(&bus->devices)) {
+                       err("%s: No new device found\n", __FUNCTION__);
+                       return NULL;
+               }
+               list_for_each_entry(dev, &bus->devices, bus_list) {
+                       if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+                               rpaphp_pci_config_bridge(dev);
+
+                       rpaphp_eeh_add_bus_device(bus);
+               }
        }
 
        return dev;
 }
 
-static void enable_eeh(struct device_node *dn)
+void rpaphp_eeh_init_nodes(struct device_node *dn)
 {
        struct device_node *sib;
 
        for (sib = dn->child; sib; sib = sib->sibling) 
-               enable_eeh(sib);
+               rpaphp_eeh_init_nodes(sib);
        eeh_add_device_early(dn);
        return;
        
 }
+EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
 
 static void print_slot_pci_funcs(struct pci_bus *bus)
 {
@@ -289,7 +324,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus)
        if (!dn)
                goto exit;
 
-       enable_eeh(dn);
+       rpaphp_eeh_init_nodes(dn);
        dev = rpaphp_pci_config_slot(bus);
        if (!dev) {
                err("%s: can't find any devices.\n", __FUNCTION__);
@@ -331,6 +366,7 @@ int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
        }
        return 0;
 }
+EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
 
 static int setup_pci_hotplug_slot_info(struct slot *slot)
 {
@@ -444,8 +480,8 @@ int rpaphp_enable_pci_slot(struct slot *slot)
                retval = rpaphp_config_pci_adapter(slot->bus);
                if (!retval) {
                        slot->state = CONFIGURED;
-                       dbg("%s: PCI devices in slot[%s] has been configured\n", 
-                               __FUNCTION__, slot->name);
+                       info("%s: devices in slot[%s] configured\n",
+                                       __FUNCTION__, slot->name);
                } else {
                        slot->state = NOT_CONFIGURED;
                        dbg("%s: no pci_dev struct for adapter in slot[%s]\n",