diff options
Diffstat (limited to 'arch/powerpc/kernel/eeh_pe.c')
| -rw-r--r-- | arch/powerpc/kernel/eeh_pe.c | 86 | 
1 files changed, 40 insertions, 46 deletions
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index fbd01eba4473..00e3844525a6 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -32,9 +32,24 @@  #include <asm/pci-bridge.h>  #include <asm/ppc-pci.h> +static int eeh_pe_aux_size = 0;  static LIST_HEAD(eeh_phb_pe);  /** + * eeh_set_pe_aux_size - Set PE auxillary data size + * @size: PE auxillary data size + * + * Set PE auxillary data size + */ +void eeh_set_pe_aux_size(int size) +{ +	if (size < 0) +		return; + +	eeh_pe_aux_size = size; +} + +/**   * eeh_pe_alloc - Allocate PE   * @phb: PCI controller   * @type: PE type @@ -44,9 +59,16 @@ static LIST_HEAD(eeh_phb_pe);  static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)  {  	struct eeh_pe *pe; +	size_t alloc_size; + +	alloc_size = sizeof(struct eeh_pe); +	if (eeh_pe_aux_size) { +		alloc_size = ALIGN(alloc_size, cache_line_size()); +		alloc_size += eeh_pe_aux_size; +	}  	/* Allocate PHB PE */ -	pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL); +	pe = kzalloc(alloc_size, GFP_KERNEL);  	if (!pe) return NULL;  	/* Initialize PHB PE */ @@ -56,6 +78,8 @@ static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)  	INIT_LIST_HEAD(&pe->child);  	INIT_LIST_HEAD(&pe->edevs); +	pe->data = (void *)pe + ALIGN(sizeof(struct eeh_pe), +				      cache_line_size());  	return pe;  } @@ -179,7 +203,8 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root,  	void *ret;  	if (!root) { -		pr_warning("%s: Invalid PE %p\n", __func__, root); +		pr_warn("%s: Invalid PE %p\n", +			__func__, root);  		return NULL;  	} @@ -351,17 +376,6 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)  	pe->config_addr	= edev->config_addr;  	/* -	 * While doing PE reset, we probably hot-reset the -	 * upstream bridge. However, the PCI devices including -	 * the associated EEH devices might be removed when EEH -	 * core is doing recovery. So that won't safe to retrieve -	 * the bridge through downstream EEH device. We have to -	 * trace the parent PCI bus, then the upstream bridge. -	 */ -	if (eeh_probe_mode_dev()) -		pe->bus = eeh_dev_to_pci_dev(edev)->bus; - -	/*  	 * Put the new EEH PE into hierarchy tree. If the parent  	 * can't be found, the newly created PE will be attached  	 * to PHB directly. Otherwise, we have to associate the @@ -802,53 +816,33 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)   */  const char *eeh_pe_loc_get(struct eeh_pe *pe)  { -	struct pci_controller *hose;  	struct pci_bus *bus = eeh_pe_bus_get(pe); -	struct pci_dev *pdev; -	struct device_node *dn; -	const char *loc; +	struct device_node *dn = pci_bus_to_OF_node(bus); +	const char *loc = NULL; -	if (!bus) -		return "N/A"; +	if (!dn) +		goto out;  	/* PHB PE or root PE ? */  	if (pci_is_root_bus(bus)) { -		hose = pci_bus_to_host(bus); -		loc = of_get_property(hose->dn, -				"ibm,loc-code", NULL); +		loc = of_get_property(dn, "ibm,loc-code", NULL); +		if (!loc) +			loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);  		if (loc) -			return loc; -		loc = of_get_property(hose->dn, -				"ibm,io-base-loc-code", NULL); -		if (loc) -			return loc; - -		pdev = pci_get_slot(bus, 0x0); -	} else { -		pdev = bus->self; -	} - -	if (!pdev) { -		loc = "N/A"; -		goto out; -	} +			goto out; -	dn = pci_device_to_OF_node(pdev); -	if (!dn) { -		loc = "N/A"; -		goto out; +		/* Check the root port */ +		dn = dn->child; +		if (!dn) +			goto out;  	}  	loc = of_get_property(dn, "ibm,loc-code", NULL);  	if (!loc)  		loc = of_get_property(dn, "ibm,slot-location-code", NULL); -	if (!loc) -		loc = "N/A";  out: -	if (pci_is_root_bus(bus) && pdev) -		pci_dev_put(pdev); -	return loc; +	return loc ? loc : "N/A";  }  /**  |