1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * The file intends to implement dynamic creation of EEH device, which will 4 * be bound with OF node and PCI device simutaneously. The EEH devices would 5 * be foundamental information for EEH core components to work proerly. Besides, 6 * We have to support multiple situations where dynamic creation of EEH device 7 * is required: 8 * 9 * 1) Before PCI emunation starts, we need create EEH devices according to the 10 * PCI sensitive OF nodes. 11 * 2) When PCI emunation is done, we need do the binding between PCI device and 12 * the associated EEH device. 13 * 3) DR (Dynamic Reconfiguration) would create PCI sensitive OF node. EEH device 14 * will be created while PCI sensitive OF node is detected from DR. 15 * 4) PCI hotplug needs redoing the binding between PCI device and EEH device. If 16 * PHB is newly inserted, we also need create EEH devices accordingly. 17 * 18 * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012. 19 */ 20 21 #include <linux/export.h> 22 #include <linux/gfp.h> 23 #include <linux/init.h> 24 #include <linux/kernel.h> 25 #include <linux/pci.h> 26 #include <linux/string.h> 27 28 #include <asm/pci-bridge.h> 29 #include <asm/ppc-pci.h> 30 31 /** 32 * eeh_dev_init - Create EEH device according to OF node 33 * @pdn: PCI device node 34 * 35 * It will create EEH device according to the given OF node. The function 36 * might be called by PCI emunation, DR, PHB hotplug. 37 */ 38 struct eeh_dev *eeh_dev_init(struct pci_dn *pdn) 39 { 40 struct eeh_dev *edev; 41 42 /* Allocate EEH device */ 43 edev = kzalloc(sizeof(*edev), GFP_KERNEL); 44 if (!edev) 45 return NULL; 46 47 /* Associate EEH device with OF node */ 48 pdn->edev = edev; 49 edev->pdn = pdn; 50 edev->bdfn = (pdn->busno << 8) | pdn->devfn; 51 edev->controller = pdn->phb; 52 53 return edev; 54 } 55 56 /** 57 * eeh_dev_phb_init_dynamic - Create EEH devices for devices included in PHB 58 * @phb: PHB 59 * 60 * Scan the PHB OF node and its child association, then create the 61 * EEH devices accordingly 62 */ 63 void eeh_dev_phb_init_dynamic(struct pci_controller *phb) 64 { 65 /* EEH PE for PHB */ 66 eeh_phb_pe_create(phb); 67 }