diff options
Diffstat (limited to 'arch/alpha/kernel/pci.c')
| -rw-r--r-- | arch/alpha/kernel/pci.c | 181 |
1 files changed, 35 insertions, 146 deletions
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index c9ab94ee1ca..076c35cd6cd 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -43,12 +43,10 @@ const char *const pci_mem_names[] = { const char pci_hae0_name[] = "HAE0"; -/* Indicate whether we respect the PCI setup left by console. */ /* - * Make this long-lived so that we know when shutting down - * whether we probed only or not. + * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource + * assignments. */ -int pci_probe_only; /* * The PCI controller list. @@ -61,15 +59,13 @@ struct pci_controller *pci_isa_hose; * Quirks. */ -static void __init -quirk_isa_bridge(struct pci_dev *dev) +static void quirk_isa_bridge(struct pci_dev *dev) { dev->class = PCI_CLASS_BRIDGE_ISA << 8; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_isa_bridge); -static void __init -quirk_cypress(struct pci_dev *dev) +static void quirk_cypress(struct pci_dev *dev) { /* The Notorious Cy82C693 chip. */ @@ -108,8 +104,7 @@ quirk_cypress(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, quirk_cypress); /* Called for each device after PCI setup is done. */ -static void __init -pcibios_fixup_final(struct pci_dev *dev) +static void pcibios_fixup_final(struct pci_dev *dev) { unsigned int class = dev->class >> 8; @@ -200,22 +195,15 @@ pcibios_init(void) subsys_initcall(pcibios_init); -char * __devinit -pcibios_setup(char *str) -{ - return str; -} - #ifdef ALPHA_RESTORE_SRM_SETUP static struct pdev_srm_saved_conf *srm_saved_configs; -void __devinit -pdev_save_srm_config(struct pci_dev *dev) +void pdev_save_srm_config(struct pci_dev *dev) { struct pdev_srm_saved_conf *tmp; static int printed = 0; - if (!alpha_using_srm || pci_probe_only) + if (!alpha_using_srm || pci_has_flag(PCI_PROBE_ONLY)) return; if (!printed) { @@ -242,7 +230,7 @@ pci_restore_srm_config(void) struct pdev_srm_saved_conf *tmp; /* No need to restore if probed only. */ - if (pci_probe_only) + if (pci_has_flag(PCI_PROBE_ONLY)) return; /* Restore SRM config. */ @@ -252,116 +240,20 @@ pci_restore_srm_config(void) } #endif -void __devinit -pcibios_fixup_resource(struct resource *res, struct resource *root) -{ - res->start += root->start; - res->end += root->start; -} - -void __devinit -pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus) { - /* Update device resources. */ - struct pci_controller *hose = (struct pci_controller *)bus->sysdata; - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (!dev->resource[i].start) - continue; - if (dev->resource[i].flags & IORESOURCE_IO) - pcibios_fixup_resource(&dev->resource[i], - hose->io_space); - else if (dev->resource[i].flags & IORESOURCE_MEM) - pcibios_fixup_resource(&dev->resource[i], - hose->mem_space); - } -} - -void __devinit -pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Propagate hose info into the subordinate devices. */ - - struct pci_controller *hose = bus->sysdata; struct pci_dev *dev = bus->self; - if (!dev) { - /* Root bus. */ - u32 pci_mem_end; - u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0; - unsigned long end; - - bus->resource[0] = hose->io_space; - bus->resource[1] = hose->mem_space; - - /* Adjust hose mem_space limit to prevent PCI allocations - in the iommu windows. */ - pci_mem_end = min((u32)__direct_map_base, sg_base) - 1; - end = hose->mem_space->start + pci_mem_end; - if (hose->mem_space->end > end) - hose->mem_space->end = end; - } else if (pci_probe_only && + if (pci_has_flag(PCI_PROBE_ONLY) && dev && (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { pci_read_bridge_bases(bus); - pcibios_fixup_device_resources(dev, bus); } list_for_each_entry(dev, &bus->devices, bus_list) { pdev_save_srm_config(dev); - if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) - pcibios_fixup_device_resources(dev, bus); } } -void __init -pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_space->start; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_space->start; - - region->start = res->start - offset; - region->end = res->end - offset; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_controller *hose = (struct pci_controller *)dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_space->start; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_space->start; - - res->start = region->start + offset; - res->end = region->end + offset; -} - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); -#endif - -int -pcibios_enable_device(struct pci_dev *dev, int mask) -{ - return pci_enable_resources(dev, mask); -} - /* * If we set up a device for bus mastering, we need to check the latency * timer as certain firmware forgets to set it properly, as seen @@ -392,7 +284,8 @@ pcibios_claim_one_bus(struct pci_bus *b) if (r->parent || !r->start || !r->flags) continue; - if (pci_probe_only || (r->flags & IORESOURCE_PCI_FIXED)) + if (pci_has_flag(PCI_PROBE_ONLY) || + (r->flags & IORESOURCE_PCI_FIXED)) pci_claim_resource(dev, i); } } @@ -414,16 +307,36 @@ void __init common_init_pci(void) { struct pci_controller *hose; + struct list_head resources; struct pci_bus *bus; int next_busno; int need_domain_info = 0; + u32 pci_mem_end; + u32 sg_base; + unsigned long end; /* Scan all of the recorded PCI controllers. */ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { - bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose); + sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0; + + /* Adjust hose mem_space limit to prevent PCI allocations + in the iommu windows. */ + pci_mem_end = min((u32)__direct_map_base, sg_base) - 1; + end = hose->mem_space->start + pci_mem_end; + if (hose->mem_space->end > end) + hose->mem_space->end = end; + + INIT_LIST_HEAD(&resources); + pci_add_resource_offset(&resources, hose->io_space, + hose->io_space->start); + pci_add_resource_offset(&resources, hose->mem_space, + hose->mem_space->start); + + bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, + hose, &resources); hose->bus = bus; hose->need_domain_info = need_domain_info; - next_busno = bus->subordinate + 1; + next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { @@ -508,30 +421,7 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn) return -EOPNOTSUPP; } -/* Create an __iomem token from a PCI BAR. Copied from lib/iomap.c with - no changes, since we don't want the other things in that object file. */ - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - /* Not checking IORESOURCE_CACHEABLE because alpha does - not distinguish between ioremap and ioremap_nocache. */ - return ioremap(start, len); - } - return NULL; -} - -/* Destroy that token. Not copied from lib/iomap.c. */ +/* Destroy an __iomem token. Not copied from lib/iomap.c. */ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { @@ -539,7 +429,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) iounmap(addr); } -EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); /* FIXME: Some boxes have multiple ISA bridges! */ |
