From fe830ef62ac6d8814e27b7e2f632848694b0e5c7 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sat, 25 May 2013 21:48:29 +0800 Subject: PCI: Introduce pci_bus_{get|put}() to manage PCI bus reference count Introduce helper functions pci_bus_{get|put}() to manage PCI bus reference count. Signed-off-by: Jiang Liu Signed-off-by: Yijing Wang Signed-off-by: Gu Zheng Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/pci.h') diff --git a/include/linux/pci.h b/include/linux/pci.h index 3a24e4ff324..7556c590ddf 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1018,6 +1018,8 @@ 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 */ +struct pci_bus *pci_bus_get(struct pci_bus *bus); +void pci_bus_put(struct pci_bus *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); -- cgit v1.2.3-70-g09d2 From 3c6e6ae770f338ef3e54c5823c21063204f53537 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Sat, 25 May 2013 21:48:30 +0800 Subject: PCI: Introduce pci_alloc_dev(struct pci_bus*) to replace alloc_pci_dev() Here we introduce a new interface to replace alloc_pci_dev(): struct pci_dev *pci_alloc_dev(struct pci_bus *bus) It takes a "struct pci_bus *" argument, so we can alloc a PCI device on a target PCI bus, and it acquires a reference on the pci_bus. We use pci_alloc_dev(NULL) to simplify the old alloc_pci_dev(), and keep it for a while but mark it as __deprecated. Holding a reference to the pci_bus ensures that referencing pci_dev->bus is valid as long as the pci_dev is valid. [bhelgaas: keep existing "return error early" structure in pci_alloc_dev()] Signed-off-by: Gu Zheng Signed-off-by: Jiang Liu Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 9 ++++++++- include/linux/pci.h | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'include/linux/pci.h') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 70f10fa3c1b..d47ce1400c2 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1200,7 +1200,7 @@ static void pci_release_bus_bridge_dev(struct device *dev) kfree(bridge); } -struct pci_dev *alloc_pci_dev(void) +struct pci_dev *pci_alloc_dev(struct pci_bus *bus) { struct pci_dev *dev; @@ -1210,9 +1210,16 @@ struct pci_dev *alloc_pci_dev(void) INIT_LIST_HEAD(&dev->bus_list); dev->dev.type = &pci_dev_type; + dev->bus = pci_bus_get(bus); return dev; } +EXPORT_SYMBOL(pci_alloc_dev); + +struct pci_dev *alloc_pci_dev(void) +{ + return pci_alloc_dev(NULL); +} EXPORT_SYMBOL(alloc_pci_dev); bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, diff --git a/include/linux/pci.h b/include/linux/pci.h index 7556c590ddf..b0f4a826411 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -364,7 +364,8 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev) return dev; } -struct pci_dev *alloc_pci_dev(void); +struct pci_dev *pci_alloc_dev(struct pci_bus *bus); +struct pci_dev * __deprecated alloc_pci_dev(void); #define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) -- cgit v1.2.3-70-g09d2 From 6ae32c539c0412ca789fb6041be45eeabf78431c Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 4 Jun 2013 19:18:14 +0200 Subject: PCI: Add pcibios_release_device() Platforms may want to provide architecture-specific functionality when a PCI device is released. Add a pcibios_release_device() call that architectures can override to do so. Signed-off-by: Sebastian Ott Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 10 ++++++++++ drivers/pci/probe.c | 1 + include/linux/pci.h | 1 + 3 files changed, 12 insertions(+) (limited to 'include/linux/pci.h') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e5f4e55d407..709791b70ca 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1334,6 +1334,16 @@ int __weak pcibios_add_device (struct pci_dev *dev) return 0; } +/** + * pcibios_release_device - provide arch specific hooks when releasing device dev + * @dev: the PCI device being released + * + * Permits the platform to provide architecture specific functionality when + * devices are released. This is the default implementation. Architecture + * implementations can override this. + */ +void __weak pcibios_release_device(struct pci_dev *dev) {} + /** * pcibios_disable_device - disable arch specific PCI resources for device dev * @dev: the PCI device to disable diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 70f10fa3c1b..58cc0a8a097 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1132,6 +1132,7 @@ static void pci_release_dev(struct device *dev) pci_dev = to_pci_dev(dev); pci_release_capabilities(pci_dev); pci_release_of_node(pci_dev); + pcibios_release_device(pci_dev); kfree(pci_dev); } diff --git a/include/linux/pci.h b/include/linux/pci.h index 3a24e4ff324..8f170e9073a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1643,6 +1643,7 @@ void pcibios_set_master(struct pci_dev *dev); int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); int pcibios_add_device(struct pci_dev *dev); +void pcibios_release_device(struct pci_dev *dev); #ifdef CONFIG_PCI_MMCONFIG void __init pci_mmcfg_early_init(void); -- cgit v1.2.3-70-g09d2