powerpc/pci: Introduce pci_remove_device_node_info()
authorGavin Shan <gwshan@linux.vnet.ibm.com>
Tue, 3 May 2016 05:41:41 +0000 (15:41 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 11 May 2016 11:54:25 +0000 (21:54 +1000)
This implements and exports pci_remove_device_node_info(). It's
used to remove the pdn (struct pci_dn) for the indicated device
node. The function is going to be used by PowerNV PCI hotplug
driver.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/kernel/pci_dn.c

index 07b94ec..467c0b0 100644 (file)
@@ -237,6 +237,7 @@ extern struct pci_dn *add_dev_pci_data(struct pci_dev *pdev);
 extern void remove_dev_pci_data(struct pci_dev *pdev);
 extern struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
                                               struct device_node *dn);
+extern void pci_remove_device_node_info(struct device_node *dn);
 
 static inline int pci_device_from_OF_node(struct device_node *np,
                                          u8 *bus, u8 *devfn)
index 0a249ff..ce10281 100644 (file)
@@ -331,6 +331,29 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
 }
 EXPORT_SYMBOL_GPL(pci_add_device_node_info);
 
+void pci_remove_device_node_info(struct device_node *dn)
+{
+       struct pci_dn *pdn = dn ? PCI_DN(dn) : NULL;
+#ifdef CONFIG_EEH
+       struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+
+       if (edev)
+               edev->pdn = NULL;
+#endif
+
+       if (!pdn)
+               return;
+
+       WARN_ON(!list_empty(&pdn->child_list));
+       list_del(&pdn->list);
+       if (pdn->parent)
+               of_node_put(pdn->parent->node);
+
+       dn->data = NULL;
+       kfree(pdn);
+}
+EXPORT_SYMBOL_GPL(pci_remove_device_node_info);
+
 /*
  * Traverse a device tree stopping each PCI device in the tree.
  * This is done depth first.  As each node is processed, a "pre"