diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-05 16:22:45 +0200 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-05 16:22:45 +0200 |
commit | 593d0a3e9f813db910dc50574532914db21d09ff (patch) | |
tree | 12d8413ee57b4383ca8c906996ffe02be6d377a5 /drivers/pci/setup-bus.c | |
parent | xen/p2m: Fix one-off error in checking the P2M tree directory. (diff) | |
parent | Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/... (diff) | |
download | linux-593d0a3e9f813db910dc50574532914db21d09ff.tar.xz linux-593d0a3e9f813db910dc50574532914db21d09ff.zip |
Merge commit '4cb38750d49010ae72e718d46605ac9ba5a851b4' into stable/for-linus-3.6
* commit '4cb38750d49010ae72e718d46605ac9ba5a851b4': (6849 commits)
bcma: fix invalid PMU chip control masks
[libata] pata_cmd64x: whitespace cleanup
libata-acpi: fix up for acpi_pm_device_sleep_state API
sata_dwc_460ex: device tree may specify dma_channel
ahci, trivial: fixed coding style issues related to braces
ahci_platform: add hibernation callbacks
libata-eh.c: local functions should not be exposed globally
libata-transport.c: local functions should not be exposed globally
sata_dwc_460ex: support hardreset
ata: use module_pci_driver
drivers/ata/pata_pcmcia.c: adjust suspicious bit operation
pata_imx: Convert to clk_prepare_enable/clk_disable_unprepare
ahci: Enable SB600 64bit DMA on MSI K9AGM2 (MS-7327) v2
[libata] Prevent interface errors with Seagate FreeAgent GoFlex
drivers/acpi/glue: revert accidental license-related 6b66d95895c bits
libata-acpi: add missing inlines in libata.h
i2c-omap: Add support for I2C_M_STOP message flag
i2c: Fall back to emulated SMBus if the operation isn't supported natively
i2c: Add SCCB support
i2c-tiny-usb: Add support for the Robofuzz OSIF USB/I2C converter
...
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r-- | drivers/pci/setup-bus.c | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8fa2d4be88de..fb506137aaee 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -265,7 +265,7 @@ out: * assign_requested_resources_sorted() - satisfy resource requests * * @head : head of the list tracking requests for resources - * @failed_list : head of the list tracking requests that could + * @fail_head : head of the list tracking requests that could * not be allocated * * Satisfy resource requests of each element in the list. Add @@ -308,7 +308,7 @@ static void __assign_resources_sorted(struct list_head *head, * Should not assign requested resources at first. * they could be adjacent, so later reassign can not reallocate * them one by one in parent resource window. - * Try to assign requested + add_size at begining + * Try to assign requested + add_size at beginning * if could do that, could get out early. * if could not do that, we still try to assign requested at first, * then try to reassign add_size for some resources. @@ -404,8 +404,8 @@ void pci_setup_cardbus(struct pci_bus *bus) struct resource *res; struct pci_bus_region region; - dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", - bus->secondary, bus->subordinate); + dev_info(&bridge->dev, "CardBus bridge to %pR\n", + &bus->busn_res); res = bus->resource[0]; pcibios_resource_to_bus(bridge, ®ion, res); @@ -469,16 +469,23 @@ static void pci_setup_bridge_io(struct pci_bus *bus) struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; + unsigned long io_mask; + u8 io_base_lo, io_limit_lo; u32 l, io_upper16; + io_mask = PCI_IO_RANGE_MASK; + if (bridge->io_window_1k) + io_mask = PCI_IO_1K_RANGE_MASK; + /* Set up the top and bottom of the PCI I/O segment for this bus. */ res = bus->resource[0]; pcibios_resource_to_bus(bridge, ®ion, res); if (res->flags & IORESOURCE_IO) { pci_read_config_dword(bridge, PCI_IO_BASE, &l); l &= 0xffff0000; - l |= (region.start >> 8) & 0x00f0; - l |= region.end & 0xf000; + io_base_lo = (region.start >> 8) & io_mask; + io_limit_lo = (region.end >> 8) & io_mask; + l |= ((u32) io_limit_lo << 8) | io_base_lo; /* Set up upper 16 bits of I/O base/limit. */ io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); dev_info(&bridge->dev, " bridge window %pR\n", res); @@ -553,8 +560,8 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) { struct pci_dev *bridge = bus->self; - dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", - bus->secondary, bus->subordinate); + dev_info(&bridge->dev, "PCI bridge to %pR\n", + &bus->busn_res); if (type & IORESOURCE_IO) pci_setup_bridge_io(bus); @@ -699,7 +706,7 @@ static resource_size_t calculate_memsize(resource_size_t size, * @realloc_head : track the additional io window on this list * * Sizing the IO windows of the PCI-PCI bridge is trivial, - * since these windows have 4K granularity and the IO ranges + * since these windows have 1K or 4K granularity and the IO ranges * of non-bridge PCI devices are limited to 256 bytes. * We must be careful with the ISA aliasing though. */ @@ -710,10 +717,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); unsigned long size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; + resource_size_t min_align = 4096, align; if (!b_res) return; + /* + * Per spec, I/O windows are 4K-aligned, but some bridges have an + * extension to support 1K alignment. + */ + if (bus->self->io_window_1k) + min_align = 1024; list_for_each_entry(dev, &bus->devices, bus_list) { int i; @@ -731,34 +745,43 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, else size1 += r_size; + align = pci_resource_alignment(dev, r); + if (align > min_align) + min_align = align; + if (realloc_head) children_add_size += get_res_add_size(realloc_head, r); } } + + if (min_align > 4096) + min_align = 4096; + size0 = calculate_iosize(size, min_size, size1, - resource_size(b_res), 4096); + resource_size(b_res), min_align); if (children_add_size > add_size) add_size = children_add_size; size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : calculate_iosize(size, min_size, add_size + size1, - resource_size(b_res), 4096); + resource_size(b_res), min_align); if (!size0 && !size1) { if (b_res->start || b_res->end) dev_info(&bus->self->dev, "disabling bridge window " - "%pR to [bus %02x-%02x] (unused)\n", b_res, - bus->secondary, bus->subordinate); + "%pR to %pR (unused)\n", b_res, + &bus->busn_res); b_res->flags = 0; return; } - /* Alignment of the IO window is always 4K */ - b_res->start = 4096; + + b_res->start = min_align; b_res->end = b_res->start + size0 - 1; b_res->flags |= IORESOURCE_STARTALIGN; if (size1 > size0 && realloc_head) { - add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); + add_to_list(realloc_head, bus->self, b_res, size1-size0, + min_align); dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " - "%pR to [bus %02x-%02x] add_size %lx\n", b_res, - bus->secondary, bus->subordinate, size1-size0); + "%pR to %pR add_size %lx\n", b_res, + &bus->busn_res, size1-size0); } } @@ -863,8 +886,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (!size0 && !size1) { if (b_res->start || b_res->end) dev_info(&bus->self->dev, "disabling bridge window " - "%pR to [bus %02x-%02x] (unused)\n", b_res, - bus->secondary, bus->subordinate); + "%pR to %pR (unused)\n", b_res, + &bus->busn_res); b_res->flags = 0; return 1; } @@ -874,8 +897,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (size1 > size0 && realloc_head) { add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " - "%pR to [bus %02x-%02x] add_size %llx\n", b_res, - bus->secondary, bus->subordinate, (unsigned long long)size1-size0); + "%pR to %pR add_size %llx\n", b_res, + &bus->busn_res, (unsigned long long)size1-size0); } return 1; } |