diff options
Diffstat (limited to 'arch/powerpc/kernel/pci_dn.c')
| -rw-r--r-- | arch/powerpc/kernel/pci_dn.c | 80 | 
1 files changed, 26 insertions, 54 deletions
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index d56b35ee7f7..1f61fab59d9 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -22,6 +22,7 @@  #include <linux/kernel.h>  #include <linux/pci.h>  #include <linux/string.h> +#include <linux/export.h>  #include <linux/init.h>  #include <linux/gfp.h> @@ -31,33 +32,44 @@  #include <asm/ppc-pci.h>  #include <asm/firmware.h> +struct pci_dn *pci_get_pdn(struct pci_dev *pdev) +{ +	struct device_node *dn = pci_device_to_OF_node(pdev); +	if (!dn) +		return NULL; +	return PCI_DN(dn); +} +  /*   * Traverse_func that inits the PCI fields of the device node.   * NOTE: this *must* be done before read/write config to the device.   */ -void * __devinit update_dn_pci_info(struct device_node *dn, void *data) +void *update_dn_pci_info(struct device_node *dn, void *data)  {  	struct pci_controller *phb = data; -	const int *type = -		of_get_property(dn, "ibm,pci-config-space-type", NULL); -	const u32 *regs; +	const __be32 *type = of_get_property(dn, "ibm,pci-config-space-type", NULL); +	const __be32 *regs;  	struct pci_dn *pdn; -	pdn = alloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL); +	pdn = zalloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);  	if (pdn == NULL)  		return NULL; -	memset(pdn, 0, sizeof(*pdn));  	dn->data = pdn;  	pdn->node = dn;  	pdn->phb = phb; +#ifdef CONFIG_PPC_POWERNV +	pdn->pe_number = IODA_INVALID_PE; +#endif  	regs = of_get_property(dn, "reg", NULL);  	if (regs) { +		u32 addr = of_read_number(regs, 1); +  		/* First register entry is addr (00BBSS00)  */ -		pdn->busno = (regs[0] >> 16) & 0xff; -		pdn->devfn = (regs[0] >> 8) & 0xff; +		pdn->busno = (addr >> 16) & 0xff; +		pdn->devfn = (addr >> 8) & 0xff;  	} -	pdn->pci_ext_config_space = (type && *type == 1); +	pdn->pci_ext_config_space = (type && of_read_number(type, 1) == 1);  	return NULL;  } @@ -87,12 +99,13 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,  	/* We started with a phb, iterate all childs */  	for (dn = start->child; dn; dn = nextdn) { -		const u32 *classp; -		u32 class; +		const __be32 *classp; +		u32 class = 0;  		nextdn = NULL;  		classp = of_get_property(dn, "class-code", NULL); -		class = classp ? *classp : 0; +		if (classp) +			class = of_read_number(classp, 1);  		if (pre && ((ret = pre(dn, data)) != NULL))  			return ret; @@ -126,7 +139,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,   * subsystem is set up, before kmalloc is valid) and during the    * dynamic lpar operation of adding a PHB to a running system.   */ -void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) +void pci_devs_phb_init_dynamic(struct pci_controller *phb)  {  	struct device_node *dn = phb->dn;  	struct pci_dn *pdn; @@ -143,47 +156,6 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)  	traverse_pci_devices(dn, update_dn_pci_info, phb);  } -/* - * Traversal func that looks for a <busno,devfcn> value. - * If found, the pci_dn is returned (thus terminating the traversal). - */ -static void *is_devfn_node(struct device_node *dn, void *data) -{ -	int busno = ((unsigned long)data >> 8) & 0xff; -	int devfn = ((unsigned long)data) & 0xff; -	struct pci_dn *pci = dn->data; - -	if (pci && (devfn == pci->devfn) && (busno == pci->busno)) -		return dn; -	return NULL; -} - -/* - * This is the "slow" path for looking up a device_node from a - * pci_dev.  It will hunt for the device under its parent's - * phb and then update sysdata for a future fastpath. - * - * It may also do fixups on the actual device since this happens - * on the first read/write. - * - * Note that it also must deal with devices that don't exist. - * In this case it may probe for real hardware ("just in case") - * and add a device_node to the device tree if necessary. - * - */ -struct device_node *fetch_dev_dn(struct pci_dev *dev) -{ -	struct device_node *orig_dn = dev->sysdata; -	struct device_node *dn; -	unsigned long searchval = (dev->bus->number << 8) | dev->devfn; - -	dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval); -	if (dn) -		dev->sysdata = dn; -	return dn; -} -EXPORT_SYMBOL(fetch_dev_dn); -  /**    * pci_devs_phb_init - Initialize phbs and pci devs under them.   *   | 
