@@ -137,7 +137,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
- dev->bus = bus;
+ dev->bus = pci_bus_get(bus);
dev->dev.of_node = of_node_get(node);
dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type;
@@ -17,6 +17,20 @@
#include <linux/slab.h>
#include "pci.h"
+struct pci_bus *pci_bus_get(struct pci_bus *bus)
+{
+ if (bus)
+ get_device(&bus->dev);
+ return bus;
+}
+EXPORT_SYMBOL(pci_bus_get);
+
+void pci_bus_put(struct pci_bus *bus)
+{
+ if (bus)
+ put_device(&bus->dev);
+}
+EXPORT_SYMBOL(pci_bus_put);
void pci_add_resource_offset(struct list_head *resources, struct resource *res,
resource_size_t offset)
@@ -73,6 +73,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
u64 size;
char buf[VIRTFN_ID_LEN];
struct pci_dev *virtfn;
+ struct pci_bus *bus;
struct resource *res;
struct pci_sriov *iov = dev->sriov;
@@ -81,7 +82,8 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
return -ENOMEM;
mutex_lock(&iov->dev->sriov->lock);
- virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+ bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+ virtfn->bus = pci_bus_get(bus);
if (!virtfn->bus) {
kfree(virtfn);
mutex_unlock(&iov->dev->sriov->lock);
@@ -1265,7 +1265,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
if (!dev)
return NULL;
- dev->bus = bus;
+ dev->bus = pci_bus_get(bus);
dev->devfn = devfn;
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
@@ -1000,6 +1000,9 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);
void pci_release_selected_regions(struct pci_dev *, int);
/* drivers/pci/bus.c */
+extern struct pci_bus *pci_bus_get(struct pci_bus *);
+extern void pci_bus_put(struct pci_bus *);
+
void pci_add_resource(struct list_head *resources, struct resource *res);
void pci_add_resource_offset(struct list_head *resources, struct resource *res,
resource_size_t offset);