diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
| -rw-r--r-- | arch/powerpc/kernel/pci-common.c | 681 | 
1 files changed, 314 insertions, 367 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 10a44e68ef1..b49c72fd7f1 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -21,13 +21,17 @@  #include <linux/string.h>  #include <linux/init.h>  #include <linux/bootmem.h> +#include <linux/delay.h> +#include <linux/export.h>  #include <linux/of_address.h> +#include <linux/of_pci.h>  #include <linux/mm.h>  #include <linux/list.h>  #include <linux/syscalls.h>  #include <linux/irq.h>  #include <linux/vmalloc.h>  #include <linux/slab.h> +#include <linux/vgaarb.h>  #include <asm/processor.h>  #include <asm/io.h> @@ -36,7 +40,6 @@  #include <asm/byteorder.h>  #include <asm/machdep.h>  #include <asm/ppc-pci.h> -#include <asm/firmware.h>  #include <asm/eeh.h>  static DEFINE_SPINLOCK(hose_spinlock); @@ -48,9 +51,6 @@ static int global_phb_number;		/* Global phb counter */  /* ISA Memory physical address */  resource_size_t isa_mem_base; -/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ -unsigned int ppc_pci_flags = 0; -  static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; @@ -101,12 +101,51 @@ void pcibios_free_controller(struct pci_controller *phb)  		kfree(phb);  } +/* + * The function is used to return the minimal alignment + * for memory or I/O windows of the associated P2P bridge. + * By default, 4KiB alignment for I/O windows and 1MiB for + * memory windows. + */ +resource_size_t pcibios_window_alignment(struct pci_bus *bus, +					 unsigned long type) +{ +	if (ppc_md.pcibios_window_alignment) +		return ppc_md.pcibios_window_alignment(bus, type); + +	/* +	 * PCI core will figure out the default +	 * alignment: 4KiB for I/O and 1MiB for +	 * memory window. +	 */ +	return 1; +} + +void pcibios_reset_secondary_bus(struct pci_dev *dev) +{ +	u16 ctrl; + +	if (ppc_md.pcibios_reset_secondary_bus) { +		ppc_md.pcibios_reset_secondary_bus(dev); +		return; +	} + +	pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl); +	ctrl |= PCI_BRIDGE_CTL_BUS_RESET; +	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); +	msleep(2); + +	ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; +	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); +	ssleep(1); +} +  static resource_size_t pcibios_io_size(const struct pci_controller *hose)  {  #ifdef CONFIG_PPC64  	return hose->pci_io_size;  #else -	return hose->io_resource.end - hose->io_resource.start + 1; +	return resource_size(&hose->io_resource);  #endif  } @@ -182,62 +221,23 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)  	return NULL;  } -static ssize_t pci_show_devspec(struct device *dev, -		struct device_attribute *attr, char *buf) -{ -	struct pci_dev *pdev; -	struct device_node *np; - -	pdev = to_pci_dev (dev); -	np = pci_device_to_OF_node(pdev); -	if (np == NULL || np->full_name == NULL) -		return 0; -	return sprintf(buf, "%s", np->full_name); -} -static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); - -/* Add sysfs properties */ -int pcibios_add_platform_entries(struct pci_dev *pdev) -{ -	return device_create_file(&pdev->dev, &dev_attr_devspec); -} - -char __devinit *pcibios_setup(char *str) -{ -	return str; -} -  /*   * Reads the interrupt pin to determine if interrupt is use by card.   * If the interrupt is used, then gets the interrupt line from the   * openfirmware and sets it in the pci_dev and pci_config line.   */ -int pci_read_irq_line(struct pci_dev *pci_dev) +static int pci_read_irq_line(struct pci_dev *pci_dev)  { -	struct of_irq oirq; +	struct of_phandle_args oirq;  	unsigned int virq; -	/* The current device-tree that iSeries generates from the HV -	 * PCI informations doesn't contain proper interrupt routing, -	 * and all the fallback would do is print out crap, so we -	 * don't attempt to resolve the interrupts here at all, some -	 * iSeries specific fixup does it. -	 * -	 * In the long run, we will hopefully fix the generated device-tree -	 * instead. -	 */ -#ifdef CONFIG_PPC_ISERIES -	if (firmware_has_feature(FW_FEATURE_ISERIES)) -		return -1; -#endif -  	pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));  #ifdef DEBUG  	memset(&oirq, 0xff, sizeof(oirq));  #endif  	/* Try to get a mapping from the device-tree */ -	if (of_irq_map_pci(pci_dev, &oirq)) { +	if (of_irq_parse_pci(pci_dev, &oirq)) {  		u8 line, pin;  		/* If that fails, lets fallback to what is in the config @@ -260,15 +260,13 @@ int pci_read_irq_line(struct pci_dev *pci_dev)  		virq = irq_create_mapping(NULL, line);  		if (virq != NO_IRQ) -			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); +			irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);  	} else {  		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", -			 oirq.size, oirq.specifier[0], oirq.specifier[1], -			 oirq.controller ? oirq.controller->full_name : -			 "<default>"); +			 oirq.args_count, oirq.args[0], oirq.args[1], +			 of_node_full_name(oirq.np)); -		virq = irq_create_of_mapping(oirq.controller, oirq.specifier, -					     oirq.size); +		virq = irq_create_of_mapping(&oirq);  	}  	if(virq == NO_IRQ) {  		pr_debug(" Failed to map !\n"); @@ -281,7 +279,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev)  	return 0;  } -EXPORT_SYMBOL(pci_read_irq_line);  /*   * Platform support for /proc/bus/pci/X/Y mmap()s, @@ -308,7 +305,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,  	unsigned long io_offset = 0;  	int i, res_bit; -	if (hose == 0) +	if (hose == NULL)  		return NULL;		/* should never happen */  	/* If memory, add on the PCI bridge address offset */ @@ -361,7 +358,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,  				      enum pci_mmap_state mmap_state,  				      int write_combine)  { -	unsigned long prot = pgprot_val(protection);  	/* Write combine is always 0 on non-memory space mappings. On  	 * memory space, if the user didn't pass 1, we check for a @@ -378,9 +374,9 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,  	/* XXX would be nice to have a way to ask for write-through */  	if (write_combine) -		return pgprot_noncached_wc(prot); +		return pgprot_noncached_wc(protection);  	else -		return pgprot_noncached(prot); +		return pgprot_noncached(protection);  }  /* @@ -660,15 +656,6 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,   *     ranges. However, some machines (thanks Apple !) tend to split their   *     space into lots of small contiguous ranges. So we have to coalesce.   * - *   - We can only cope with all memory ranges having the same offset - *     between CPU addresses and PCI addresses. Unfortunately, some bridges - *     are setup for a large 1:1 mapping along with a small "window" which - *     maps PCI address 0 to some arbitrary high address of the CPU space in - *     order to give access to the ISA memory hole. - *     The way out of here that I've chosen for now is to always set the - *     offset based on the first resource found, then override it if we - *     have a different offset and the previous was set by an ISA hole. - *   *   - Some busses have IO space not starting at 0, which causes trouble with   *     the way we do our IO resource renumbering. The code somewhat deals with   *     it for 64 bits but I would expect problems on 32 bits. @@ -676,65 +663,39 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,   *   - Some 32 bits platforms such as 4xx can have physical space larger than   *     32 bits so we need to use 64 bits values for the parsing   */ -void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, -					    struct device_node *dev, -					    int primary) +void pci_process_bridge_OF_ranges(struct pci_controller *hose, +				  struct device_node *dev, int primary)  { -	const u32 *ranges; -	int rlen; -	int pna = of_n_addr_cells(dev); -	int np = pna + 5; -	int memno = 0, isa_hole = -1; -	u32 pci_space; -	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; -	unsigned long long isa_mb = 0; +	int memno = 0;  	struct resource *res; +	struct of_pci_range range; +	struct of_pci_range_parser parser;  	printk(KERN_INFO "PCI host bridge %s %s ranges:\n",  	       dev->full_name, primary ? "(primary)" : ""); -	/* Get ranges property */ -	ranges = of_get_property(dev, "ranges", &rlen); -	if (ranges == NULL) +	/* Check for ranges property */ +	if (of_pci_range_parser_init(&parser, dev))  		return;  	/* Parse it */ -	while ((rlen -= np * 4) >= 0) { -		/* Read next ranges element */ -		pci_space = ranges[0]; -		pci_addr = of_read_number(ranges + 1, 2); -		cpu_addr = of_translate_address(dev, ranges + 3); -		size = of_read_number(ranges + pna + 3, 2); -		ranges += np; - +	for_each_of_pci_range(&parser, &range) {  		/* If we failed translation or got a zero-sized region  		 * (some FW try to feed us with non sensical zero sized regions  		 * such as power3 which look like some kind of attempt at exposing  		 * the VGA memory hole)  		 */ -		if (cpu_addr == OF_BAD_ADDR || size == 0) +		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)  			continue; -		/* Now consume following elements while they are contiguous */ -		for (; rlen >= np * sizeof(u32); -		     ranges += np, rlen -= np * 4) { -			if (ranges[0] != pci_space) -				break; -			pci_next = of_read_number(ranges + 1, 2); -			cpu_next = of_translate_address(dev, ranges + 3); -			if (pci_next != pci_addr + size || -			    cpu_next != cpu_addr + size) -				break; -			size += of_read_number(ranges + pna + 3, 2); -		} -  		/* Act based on address space type */  		res = NULL; -		switch ((pci_space >> 24) & 0x3) { -		case 1:		/* PCI IO space */ +		switch (range.flags & IORESOURCE_TYPE_BITS) { +		case IORESOURCE_IO:  			printk(KERN_INFO  			       "  IO 0x%016llx..0x%016llx -> 0x%016llx\n", -			       cpu_addr, cpu_addr + size - 1, pci_addr); +			       range.cpu_addr, range.cpu_addr + range.size - 1, +			       range.pci_addr);  			/* We support only one IO range */  			if (hose->pci_io_size) { @@ -744,11 +705,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,  			}  #ifdef CONFIG_PPC32  			/* On 32 bits, limit I/O space to 16MB */ -			if (size > 0x01000000) -				size = 0x01000000; +			if (range.size > 0x01000000) +				range.size = 0x01000000;  			/* 32 bits needs to map IOs here */ -			hose->io_base_virt = ioremap(cpu_addr, size); +			hose->io_base_virt = ioremap(range.cpu_addr, +						range.size);  			/* Expect trouble if pci_addr is not 0 */  			if (primary) @@ -758,20 +720,20 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,  			/* pci_io_size and io_base_phys always represent IO  			 * space starting at 0 so we factor in pci_addr  			 */ -			hose->pci_io_size = pci_addr + size; -			hose->io_base_phys = cpu_addr - pci_addr; +			hose->pci_io_size = range.pci_addr + range.size; +			hose->io_base_phys = range.cpu_addr - range.pci_addr;  			/* Build resource */  			res = &hose->io_resource; -			res->flags = IORESOURCE_IO; -			res->start = pci_addr; +			range.cpu_addr = range.pci_addr;  			break; -		case 2:		/* PCI Memory space */ -		case 3:		/* PCI 64 bits Memory space */ +		case IORESOURCE_MEM:  			printk(KERN_INFO  			       " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", -			       cpu_addr, cpu_addr + size - 1, pci_addr, -			       (pci_space & 0x40000000) ? "Prefetch" : ""); +			       range.cpu_addr, range.cpu_addr + range.size - 1, +			       range.pci_addr, +			       (range.pci_space & 0x40000000) ? +			       "Prefetch" : "");  			/* We support only 3 memory ranges */  			if (memno >= 3) { @@ -780,60 +742,23 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,  				continue;  			}  			/* Handles ISA memory hole space here */ -			if (pci_addr == 0) { -				isa_mb = cpu_addr; -				isa_hole = memno; +			if (range.pci_addr == 0) {  				if (primary || isa_mem_base == 0) -					isa_mem_base = cpu_addr; -				hose->isa_mem_phys = cpu_addr; -				hose->isa_mem_size = size; -			} - -			/* We get the PCI/Mem offset from the first range or -			 * the, current one if the offset came from an ISA -			 * hole. If they don't match, bugger. -			 */ -			if (memno == 0 || -			    (isa_hole >= 0 && pci_addr != 0 && -			     hose->pci_mem_offset == isa_mb)) -				hose->pci_mem_offset = cpu_addr - pci_addr; -			else if (pci_addr != 0 && -				 hose->pci_mem_offset != cpu_addr - pci_addr) { -				printk(KERN_INFO -				       " \\--> Skipped (offset mismatch) !\n"); -				continue; +					isa_mem_base = range.cpu_addr; +				hose->isa_mem_phys = range.cpu_addr; +				hose->isa_mem_size = range.size;  			}  			/* Build resource */ +			hose->mem_offset[memno] = range.cpu_addr - +							range.pci_addr;  			res = &hose->mem_resources[memno++]; -			res->flags = IORESOURCE_MEM; -			if (pci_space & 0x40000000) -				res->flags |= IORESOURCE_PREFETCH; -			res->start = cpu_addr;  			break;  		}  		if (res != NULL) { -			res->name = dev->full_name; -			res->end = res->start + size - 1; -			res->parent = NULL; -			res->sibling = NULL; -			res->child = NULL; +			of_pci_range_to_resource(&range, dev, res);  		}  	} - -	/* If there's an ISA hole and the pci_mem_offset is -not- matching -	 * the ISA hole offset, then we need to remove the ISA hole from -	 * the resource list for that brige -	 */ -	if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) { -		unsigned int next = isa_hole + 1; -		printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb); -		if (next < memno) -			memmove(&hose->mem_resources[isa_hole], -				&hose->mem_resources[next], -				sizeof(struct resource) * (memno - next)); -		hose->mem_resources[--memno].flags = 0; -	}  }  /* Decide whether to display the domain number in /proc */ @@ -841,71 +766,25 @@ int pci_proc_domain(struct pci_bus *bus)  {  	struct pci_controller *hose = pci_bus_to_host(bus); -	if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) +	if (!pci_has_flag(PCI_ENABLE_PROC_DOMAINS))  		return 0; -	if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) +	if (pci_has_flag(PCI_COMPAT_DOMAIN_0))  		return hose->global_number != 0;  	return 1;  } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -			     struct resource *res) -{ -	resource_size_t offset = 0, mask = (resource_size_t)-1; -	struct pci_controller *hose = pci_bus_to_host(dev->bus); - -	if (!hose) -		return; -	if (res->flags & IORESOURCE_IO) { -		offset = (unsigned long)hose->io_base_virt - _IO_BASE; -		mask = 0xffffffffu; -	} else if (res->flags & IORESOURCE_MEM) -		offset = hose->pci_mem_offset; - -	region->start = (res->start - offset) & mask; -	region->end = (res->end - offset) & mask; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -			     struct pci_bus_region *region) +int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)  { -	resource_size_t offset = 0, mask = (resource_size_t)-1; -	struct pci_controller *hose = pci_bus_to_host(dev->bus); +	if (ppc_md.pcibios_root_bridge_prepare) +		return ppc_md.pcibios_root_bridge_prepare(bridge); -	if (!hose) -		return; -	if (res->flags & IORESOURCE_IO) { -		offset = (unsigned long)hose->io_base_virt - _IO_BASE; -		mask = 0xffffffffu; -	} else if (res->flags & IORESOURCE_MEM) -		offset = hose->pci_mem_offset; -	res->start = (region->start + offset) & mask; -	res->end = (region->end + offset) & mask; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - -/* Fixup a bus resource into a linux resource */ -static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) -{ -	struct pci_controller *hose = pci_bus_to_host(dev->bus); -	resource_size_t offset = 0, mask = (resource_size_t)-1; - -	if (res->flags & IORESOURCE_IO) { -		offset = (unsigned long)hose->io_base_virt - _IO_BASE; -		mask = 0xffffffffu; -	} else if (res->flags & IORESOURCE_MEM) -		offset = hose->pci_mem_offset; - -	res->start = (res->start + offset) & mask; -	res->end = (res->end + offset) & mask; +	return 0;  } -  /* This header fixup will do the resource fixup for all devices as they are   * probed, but not for bridge ranges   */ -static void __devinit pcibios_fixup_resources(struct pci_dev *dev) +static void pcibios_fixup_resources(struct pci_dev *dev)  {  	struct pci_controller *hose = pci_bus_to_host(dev->bus);  	int i; @@ -917,38 +796,37 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)  	}  	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {  		struct resource *res = dev->resource + i; +		struct pci_bus_region reg;  		if (!res->flags)  			continue; -		/* On platforms that have PPC_PCI_PROBE_ONLY set, we don't -		 * consider 0 as an unassigned BAR value. It's technically -		 * a valid value, but linux doesn't like it... so when we can -		 * re-assign things, we do so, but if we can't, we keep it -		 * around and hope for the best... + +		/* If we're going to re-assign everything, we mark all resources +		 * as unset (and 0-base them). In addition, we mark BARs starting +		 * at 0 as unset as well, except if PCI_PROBE_ONLY is also set +		 * since in that case, we don't want to re-assign anything  		 */ -		if (res->start == 0 && !(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { -			pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n", -				 pci_name(dev), i, -				 (unsigned long long)res->start, -				 (unsigned long long)res->end, -				 (unsigned int)res->flags); +		pcibios_resource_to_bus(dev->bus, ®, res); +		if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) || +		    (reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { +			/* Only print message if not re-assigning */ +			if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) +				pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " +					 "is unassigned\n", +					 pci_name(dev), i, +					 (unsigned long long)res->start, +					 (unsigned long long)res->end, +					 (unsigned int)res->flags);  			res->end -= res->start;  			res->start = 0;  			res->flags |= IORESOURCE_UNSET;  			continue;  		} -		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", +		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n",  			 pci_name(dev), i,  			 (unsigned long long)res->start,\  			 (unsigned long long)res->end,  			 (unsigned int)res->flags); - -		fixup_resource(res, dev); - -		pr_debug("PCI:%s            %016llx-%016llx\n", -			 pci_name(dev), -			 (unsigned long long)res->start, -			 (unsigned long long)res->end);  	}  	/* Call machine specific resource fixup */ @@ -962,25 +840,26 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);   * things go more smoothly when it gets it right. It should covers cases such   * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges   */ -static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus, -							   struct resource *res) +static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, +						 struct resource *res)  {  	struct pci_controller *hose = pci_bus_to_host(bus);  	struct pci_dev *dev = bus->self;  	resource_size_t offset; +	struct pci_bus_region region;  	u16 command;  	int i;  	/* We don't do anything if PCI_PROBE_ONLY is set */ -	if (ppc_pci_flags & PPC_PCI_PROBE_ONLY) +	if (pci_has_flag(PCI_PROBE_ONLY))  		return 0;  	/* Job is a bit different between memory and IO */  	if (res->flags & IORESOURCE_MEM) { -		/* If the BAR is non-0 (res != pci_mem_offset) then it's probably been -		 * initialized by somebody -		 */ -		if (res->start != hose->pci_mem_offset) +		pcibios_resource_to_bus(dev->bus, ®ion, res); + +		/* If the BAR is non-0 then it's probably been initialized */ +		if (region.start != 0)  			return 0;  		/* The BAR is 0, let's check if memory decoding is enabled on @@ -992,11 +871,11 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,  		/* Memory decoding is enabled and the BAR is 0. If any of the bridge  		 * resources covers that starting address (0 then it's good enough for -		 * us for memory +		 * us for memory space)  		 */  		for (i = 0; i < 3; i++) {  			if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && -			    hose->mem_resources[i].start == hose->pci_mem_offset) +			    hose->mem_resources[i].start == hose->mem_offset[i])  				return 0;  		} @@ -1027,7 +906,7 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,  }  /* Fixup resources of a PCI<->PCI bridge */ -static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) +static void pcibios_fixup_bridge(struct pci_bus *bus)  {  	struct resource *res;  	int i; @@ -1040,32 +919,34 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)  		if (i >= 3 && bus->self->transparent)  			continue; -		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", +		/* If we're going to reassign everything, we can +		 * shrink the P2P resource to have size as being +		 * of 0 in order to save space. +		 */ +		if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { +			res->flags |= IORESOURCE_UNSET; +			res->start = 0; +			res->end = -1; +			continue; +		} + +		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x]\n",  			 pci_name(dev), i,  			 (unsigned long long)res->start,\  			 (unsigned long long)res->end,  			 (unsigned int)res->flags); -		/* Perform fixup */ -		fixup_resource(res, dev); -  		/* Try to detect uninitialized P2P bridge resources,  		 * and clear them out so they get re-assigned later  		 */  		if (pcibios_uninitialized_bridge_resource(bus, res)) {  			res->flags = 0;  			pr_debug("PCI:%s            (unassigned)\n", pci_name(dev)); -		} else { - -			pr_debug("PCI:%s            %016llx-%016llx\n", -				 pci_name(dev), -				 (unsigned long long)res->start, -				 (unsigned long long)res->end);  		}  	}  } -void __devinit pcibios_setup_bus_self(struct pci_bus *bus) +void pcibios_setup_bus_self(struct pci_bus *bus)  {  	/* Fix up the bus resources for P2P bridges */  	if (bus->self != NULL) @@ -1082,7 +963,39 @@ void __devinit pcibios_setup_bus_self(struct pci_bus *bus)  		ppc_md.pci_dma_bus_setup(bus);  } -void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) +static void pcibios_setup_device(struct pci_dev *dev) +{ +	/* Fixup NUMA node as it may not be setup yet by the generic +	 * code and is needed by the DMA init +	 */ +	set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); + +	/* Hook up default DMA ops */ +	set_dma_ops(&dev->dev, pci_dma_ops); +	set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); + +	/* Additional platform DMA/iommu setup */ +	if (ppc_md.pci_dma_dev_setup) +		ppc_md.pci_dma_dev_setup(dev); + +	/* Read default IRQs and fixup if necessary */ +	pci_read_irq_line(dev); +	if (ppc_md.pci_irq_fixup) +		ppc_md.pci_irq_fixup(dev); +} + +int pcibios_add_device(struct pci_dev *dev) +{ +	/* +	 * We can only call pcibios_setup_device() after bus setup is complete, +	 * since some of the platform specific DMA setup code depends on it. +	 */ +	if (dev->bus->is_added) +		pcibios_setup_device(dev); +	return 0; +} + +void pcibios_setup_bus_devices(struct pci_bus *bus)  {  	struct pci_dev *dev; @@ -1096,37 +1009,22 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)  		if (dev->is_added)  			continue; -		/* Setup OF node pointer in the device */ -		dev->dev.of_node = pci_device_to_OF_node(dev); - -		/* Fixup NUMA node as it may not be setup yet by the generic -		 * code and is needed by the DMA init -		 */ -		set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); - -		/* Hook up default DMA ops */ -		set_dma_ops(&dev->dev, pci_dma_ops); -		set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); - -		/* Additional platform DMA/iommu setup */ -		if (ppc_md.pci_dma_dev_setup) -			ppc_md.pci_dma_dev_setup(dev); - -		/* Read default IRQs and fixup if necessary */ -		pci_read_irq_line(dev); -		if (ppc_md.pci_irq_fixup) -			ppc_md.pci_irq_fixup(dev); +		pcibios_setup_device(dev);  	}  } -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void pcibios_set_master(struct pci_dev *dev) +{ +	/* No special bus mastering setup handling */ +} + +void pcibios_fixup_bus(struct pci_bus *bus)  {  	/* When called from the generic PCI probe, read PCI<->PCI bridge  	 * bases. This is -not- called when generating the PCI tree from  	 * the OF device-tree.  	 */ -	if (bus->self != NULL) -		pci_read_bridge_bases(bus); +	pci_read_bridge_bases(bus);  	/* Now fixup the bus bus */  	pcibios_setup_bus_self(bus); @@ -1136,7 +1034,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)  }  EXPORT_SYMBOL(pcibios_fixup_bus); -void __devinit pci_fixup_cardbus(struct pci_bus *bus) +void pci_fixup_cardbus(struct pci_bus *bus)  {  	/* Now fixup devices on that bus */  	pcibios_setup_bus_devices(bus); @@ -1145,7 +1043,7 @@ void __devinit pci_fixup_cardbus(struct pci_bus *bus)  static int skip_isa_ioresource_align(struct pci_dev *dev)  { -	if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && +	if (pci_has_flag(PCI_CAN_SKIP_ISA_ALIGN) &&  	    !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))  		return 1;  	return 0; @@ -1263,18 +1161,15 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)  	pci_bus_for_each_resource(bus, res, i) {  		if (!res || !res->flags || res->start > res->end || res->parent)  			continue; + +		/* If the resource was left unset at this point, we clear it */ +		if (res->flags & IORESOURCE_UNSET) +			goto clear_resource; +  		if (bus->parent == NULL)  			pr = (res->flags & IORESOURCE_IO) ?  				&ioport_resource : &iomem_resource;  		else { -			/* Don't bother with non-root busses when -			 * re-assigning all resources. We clear the -			 * resource flags as if they were colliding -			 * and as such ensure proper re-allocation -			 * later. -			 */ -			if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC) -				goto clear_resource;  			pr = pci_find_parent_resource(bus->self, res);  			if (pr == res) {  				/* this happens when the generic PCI @@ -1305,10 +1200,17 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)  			if (reparent_resources(pr, res) == 0)  				continue;  		} -		printk(KERN_WARNING "PCI: Cannot allocate resource region " -		       "%d of PCI bridge %d, will remap\n", i, bus->number); -clear_resource: -		res->start = res->end = 0; +		pr_warning("PCI: Cannot allocate resource region " +			   "%d of PCI bridge %d, will remap\n", i, bus->number); +	clear_resource: +		/* The resource might be figured out when doing +		 * reassignment based on the resources required +		 * by the downstream PCI devices. Here we set +		 * the size of the resource to be 0 in order to +		 * save more space. +		 */ +		res->start = 0; +		res->end = -1;  		res->flags = 0;  	} @@ -1316,7 +1218,7 @@ clear_resource:  		pcibios_allocate_bus_resources(b);  } -static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) +static inline void alloc_resource(struct pci_dev *dev, int idx)  {  	struct resource *pr, *r = &dev->resource[idx]; @@ -1420,10 +1322,9 @@ static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus)   no_io:  	/* Check for memory */ -	offset = hose->pci_mem_offset; -	pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset);  	for (i = 0; i < 3; i++) {  		pres = &hose->mem_resources[i]; +		offset = hose->mem_offset[i];  		if (!(pres->flags & IORESOURCE_MEM))  			continue;  		pr_debug("hose mem res: %pR\n", pres); @@ -1452,22 +1353,17 @@ void __init pcibios_resource_survey(void)  {  	struct pci_bus *b; -	/* Allocate and assign resources. If we re-assign everything, then -	 * we skip the allocate phase -	 */ +	/* Allocate and assign resources */  	list_for_each_entry(b, &pci_root_buses, node)  		pcibios_allocate_bus_resources(b); - -	if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) { -		pcibios_allocate_resources(0); -		pcibios_allocate_resources(1); -	} +	pcibios_allocate_resources(0); +	pcibios_allocate_resources(1);  	/* Before we start assigning unassigned resource, we try to reserve  	 * the low IO area and the VGA memory area if they intersect the  	 * bus available resources to avoid allocating things on top of them  	 */ -	if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { +	if (!pci_has_flag(PCI_PROBE_ONLY)) {  		list_for_each_entry(b, &pci_root_buses, node)  			pcibios_reserve_legacy_regions(b);  	} @@ -1475,7 +1371,7 @@ void __init pcibios_resource_survey(void)  	/* Now, if the platform didn't decide to blindly trust the firmware,  	 * we proceed to assigning things that were left unassigned  	 */ -	if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { +	if (!pci_has_flag(PCI_PROBE_ONLY)) {  		pr_debug("PCI: Assigning unassigned resources...\n");  		pci_assign_unassigned_resources();  	} @@ -1485,8 +1381,6 @@ void __init pcibios_resource_survey(void)  		ppc_md.pcibios_fixup();  } -#ifdef CONFIG_HOTPLUG -  /* This is used by the PCI hotplug driver to allocate resource   * of newly plugged busses. We can try to consolidate with the   * rest of the code later, for now, keep it as-is as our main @@ -1536,17 +1430,20 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)  	/* Allocate bus and devices resources */  	pcibios_allocate_bus_resources(bus);  	pcibios_claim_one_bus(bus); +	if (!pci_has_flag(PCI_PROBE_ONLY)) +		pci_assign_unassigned_bus_resources(bus); + +	/* Fixup EEH */ +	eeh_add_device_tree_late(bus);  	/* Add new devices to global lists.  Register in proc, sysfs. */  	pci_bus_add_devices(bus); -	/* Fixup EEH */ -	eeh_add_device_tree_late(bus); +	/* sysfs files should only be added after devices are added */ +	eeh_add_sysfs_files(bus);  }  EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); -#endif /* CONFIG_HOTPLUG */ -  int pcibios_enable_device(struct pci_dev *dev, int mask)  {  	if (ppc_md.pcibios_enable_device_hook) @@ -1556,61 +1453,57 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)  	return pci_enable_resources(dev, mask);  } -void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) +resource_size_t pcibios_io_space_offset(struct pci_controller *hose) +{ +	return (unsigned long) hose->io_base_virt - _IO_BASE; +} + +static void pcibios_setup_phb_resources(struct pci_controller *hose, +					struct list_head *resources)  { -	struct pci_bus *bus = hose->bus;  	struct resource *res; +	resource_size_t offset;  	int i;  	/* Hookup PHB IO resource */ -	bus->resource[0] = res = &hose->io_resource; +	res = &hose->io_resource;  	if (!res->flags) {  		printk(KERN_WARNING "PCI: I/O resource not set for host"  		       " bridge %s (domain %d)\n",  		       hose->dn->full_name, hose->global_number); -#ifdef CONFIG_PPC32 -		/* Workaround for lack of IO resource only on 32-bit */ -		res->start = (unsigned long)hose->io_base_virt - isa_io_base; -		res->end = res->start + IO_SPACE_LIMIT; -		res->flags = IORESOURCE_IO; -#endif /* CONFIG_PPC32 */ -	} +	} else { +		offset = pcibios_io_space_offset(hose); -	pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n", -		 (unsigned long long)res->start, -		 (unsigned long long)res->end, -		 (unsigned long)res->flags); +		pr_debug("PCI: PHB IO resource    = %08llx-%08llx [%lx] off 0x%08llx\n", +			 (unsigned long long)res->start, +			 (unsigned long long)res->end, +			 (unsigned long)res->flags, +			 (unsigned long long)offset); +		pci_add_resource_offset(resources, res, offset); +	}  	/* Hookup PHB Memory resources */  	for (i = 0; i < 3; ++i) {  		res = &hose->mem_resources[i];  		if (!res->flags) { -			if (i > 0) -				continue; -			printk(KERN_ERR "PCI: Memory resource 0 not set for " -			       "host bridge %s (domain %d)\n", -			       hose->dn->full_name, hose->global_number); -#ifdef CONFIG_PPC32 -			/* Workaround for lack of MEM resource only on 32-bit */ -			res->start = hose->pci_mem_offset; -			res->end = (resource_size_t)-1LL; -			res->flags = IORESOURCE_MEM; -#endif /* CONFIG_PPC32 */ +			if (i == 0) +				printk(KERN_ERR "PCI: Memory resource 0 not set for " +				       "host bridge %s (domain %d)\n", +				       hose->dn->full_name, hose->global_number); +			continue;  		} -		bus->resource[i+1] = res; +		offset = hose->mem_offset[i]; + -		pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i, +		pr_debug("PCI: PHB MEM resource %d = %08llx-%08llx [%lx] off 0x%08llx\n", i,  			 (unsigned long long)res->start,  			 (unsigned long long)res->end, -			 (unsigned long)res->flags); -	} - -	pr_debug("PCI: PHB MEM offset     = %016llx\n", -		 (unsigned long long)hose->pci_mem_offset); -	pr_debug("PCI: PHB IO  offset     = %08lx\n", -		 (unsigned long)hose->io_base_virt - _IO_BASE); +			 (unsigned long)res->flags, +			 (unsigned long long)offset); +		pci_add_resource_offset(resources, res, offset); +	}  }  /* @@ -1653,7 +1546,7 @@ fake_pci_bus(struct pci_controller *hose, int busnr)  {  	static struct pci_bus bus; -	if (hose == 0) { +	if (hose == NULL) {  		printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);  	}  	bus.number = busnr; @@ -1684,51 +1577,105 @@ int early_find_capability(struct pci_controller *hose, int bus, int devfn,  	return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);  } +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) +{ +	struct pci_controller *hose = bus->sysdata; + +	return of_node_get(hose->dn); +} +  /**   * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus   * @hose: Pointer to the PCI host controller instance structure - * @sysdata: value to use for sysdata pointer.  ppc32 and ppc64 differ here - * - * Note: the 'data' pointer is a temporary measure.  As 32 and 64 bit - * pci code gets merged, this parameter should become unnecessary because - * both will use the same value.   */ -void __devinit pcibios_scan_phb(struct pci_controller *hose, void *sysdata) +void pcibios_scan_phb(struct pci_controller *hose)  { +	LIST_HEAD(resources);  	struct pci_bus *bus;  	struct device_node *node = hose->dn;  	int mode; -	pr_debug("PCI: Scanning PHB %s\n", -		 node ? node->full_name : "<NO NAME>"); +	pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node)); + +	/* Get some IO space for the new PHB */ +	pcibios_setup_phb_io_space(hose); + +	/* Wire up PHB bus resources */ +	pcibios_setup_phb_resources(hose, &resources); + +	hose->busn.start = hose->first_busno; +	hose->busn.end	 = hose->last_busno; +	hose->busn.flags = IORESOURCE_BUS; +	pci_add_resource(&resources, &hose->busn);  	/* Create an empty bus for the toplevel */ -	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, -			     sysdata); +	bus = pci_create_root_bus(hose->parent, hose->first_busno, +				  hose->ops, hose, &resources);  	if (bus == NULL) {  		pr_err("Failed to create bus for PCI domain %04x\n",  			hose->global_number); +		pci_free_resource_list(&resources);  		return;  	} -	bus->secondary = hose->first_busno;  	hose->bus = bus; -	/* Get some IO space for the new PHB */ -	pcibios_setup_phb_io_space(hose); - -	/* Wire up PHB bus resources */ -	pcibios_setup_phb_resources(hose); -  	/* Get probe mode and perform scan */  	mode = PCI_PROBE_NORMAL;  	if (node && ppc_md.pci_probe_mode)  		mode = ppc_md.pci_probe_mode(bus);  	pr_debug("    probe mode: %d\n", mode); -	if (mode == PCI_PROBE_DEVTREE) { -		bus->subordinate = hose->last_busno; +	if (mode == PCI_PROBE_DEVTREE)  		of_scan_bus(node, bus); + +	if (mode == PCI_PROBE_NORMAL) { +		pci_bus_update_busn_res_end(bus, 255); +		hose->last_busno = pci_scan_child_bus(bus); +		pci_bus_update_busn_res_end(bus, hose->last_busno);  	} -	if (mode == PCI_PROBE_NORMAL) -		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); +	/* Platform gets a chance to do some global fixups before +	 * we proceed to resource allocation +	 */ +	if (ppc_md.pcibios_fixup_phb) +		ppc_md.pcibios_fixup_phb(hose); + +	/* Configure PCI Express settings */ +	if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { +		struct pci_bus *child; +		list_for_each_entry(child, &bus->children, node) +			pcie_bus_configure_settings(child); +	} +} + +static void fixup_hide_host_resource_fsl(struct pci_dev *dev) +{ +	int i, class = dev->class >> 8; +	/* When configured as agent, programing interface = 1 */ +	int prog_if = dev->class & 0xf; + +	if ((class == PCI_CLASS_PROCESSOR_POWERPC || +	     class == PCI_CLASS_BRIDGE_OTHER) && +		(dev->hdr_type == PCI_HEADER_TYPE_NORMAL) && +		(prog_if == 0) && +		(dev->bus->parent == NULL)) { +		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { +			dev->resource[i].start = 0; +			dev->resource[i].end = 0; +			dev->resource[i].flags = 0; +		} +	} +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); + +static void fixup_vga(struct pci_dev *pdev) +{ +	u16 cmd; + +	pci_read_config_word(pdev, PCI_COMMAND, &cmd); +	if ((cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) || !vga_default_device()) +		vga_set_default_device(pdev); +  } +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, +			      PCI_CLASS_DISPLAY_VGA, 8, fixup_vga);  | 
