[PATCH] PCI: Reduce nr of ptr derefs in drivers/pci/hotplug/rpaphp_pci.c
[powerpc.git] / drivers / pci / hotplug / rpaphp_pci.c
index f7c12d7..396b54b 100644 (file)
@@ -62,28 +62,6 @@ struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn)
 }
 EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
 
-int rpaphp_claim_resource(struct pci_dev *dev, int resource)
-{
-       struct resource *res = &dev->resource[resource];
-       struct resource *root = pci_find_parent_resource(dev, res);
-       char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
-       int err = -EINVAL;
-
-       if (root != NULL) {
-               err = request_resource(root, res);
-       }
-
-       if (err) {
-               err("PCI: %s region %d of %s %s [%lx:%lx]\n",
-                   root ? "Address space collision on" :
-                   "No parent found for",
-                   resource, dtype, pci_name(dev), res->start, res->end);
-       }
-       return err;
-}
-
-EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
-
 static int rpaphp_get_sensor_state(struct slot *slot, int *state)
 {
        int rc;
@@ -154,8 +132,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;
 
@@ -178,12 +155,26 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
 
                                if (r->parent || !r->start || !r->flags)
                                        continue;
-                               rpaphp_claim_resource(dev, i);
+                               pci_claim_resource(dev, i);
                        }
                }
        }
 }
 
+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 +208,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,35 +231,38 @@ 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);
 
-       return dev;
-}
+               /* 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);
 
-static void enable_eeh(struct device_node *dn)
-{
-       struct device_node *sib;
+                       rpaphp_eeh_add_bus_device(bus);
+               }
+       }
 
-       for (sib = dn->child; sib; sib = sib->sibling) 
-               enable_eeh(sib);
-       eeh_add_device_early(dn);
-       return;
-       
+       return dev;
 }
 
 static void print_slot_pci_funcs(struct pci_bus *bus)
@@ -289,7 +290,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus)
        if (!dn)
                goto exit;
 
-       enable_eeh(dn);
+       eeh_add_device_tree_early(dn);
        dev = rpaphp_pci_config_slot(bus);
        if (!dev) {
                err("%s: can't find any devices.\n", __FUNCTION__);
@@ -331,16 +332,18 @@ 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)
 {
+       struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info;
+
        dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",
            __FUNCTION__);
-       rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status);
+       rpaphp_get_power_status(slot, &hotplug_slot_info->power_status);
        rpaphp_get_pci_adapter_status(slot, 1,
-                                     &slot->hotplug_slot->info->
-                                     adapter_status);
-       if (slot->hotplug_slot->info->adapter_status == NOT_VALID) {
+                                     &hotplug_slot_info->adapter_status);
+       if (hotplug_slot_info->adapter_status == NOT_VALID) {
                err("%s: NOT_VALID: skip dn->full_name=%s\n",
                    __FUNCTION__, slot->dn->full_name);
                return -EINVAL;
@@ -444,8 +447,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",