aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 19:17:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 19:17:07 -0400
commit6dd53aa4563a2c69e80a24d2cc68d484b5ea2891 (patch)
tree0cca9f65984b524527910960d972fc6ef85fac88 /drivers/pci/setup-bus.c
parentf14121ab35912e3d2e57ac9a4ce1f9d4b7baeffb (diff)
parent63b96f7baeba71966c723912c3f8f0274577f877 (diff)
Merge tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Host bridge hotplug: - Add MMCONFIG support for hot-added host bridges (Jiang Liu) Device hotplug: - Move fixups from __init to __devinit (Sebastian Andrzej Siewior) - Call FINAL fixups for hot-added devices, too (Myron Stowe) - Factor out generic code for P2P bridge hot-add (Yinghai Lu) - Remove all functions in a slot, not just those with _EJx (Amos Kong) Dynamic resource management: - Track bus number allocation (struct resource tree per domain) (Yinghai Lu) - Make P2P bridge 1K I/O windows work with resource reassignment (Bjorn Helgaas, Yinghai Lu) - Disable decoding while updating 64-bit BARs (Bjorn Helgaas) Power management: - Add PCIe runtime D3cold support (Huang Ying) Virtualization: - Add VFIO infrastructure (ACS, DMA source ID quirks) (Alex Williamson) - Add quirks for devices with broken INTx masking (Jan Kiszka) Miscellaneous: - Fix some PCI Express capability version issues (Myron Stowe) - Factor out some arch code with a weak, generic, pcibios_setup() (Myron Stowe)" * tag 'for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (122 commits) PCI: hotplug: ensure a consistent return value in error case PCI: fix undefined reference to 'pci_fixup_final_inited' PCI: build resource code for M68K architecture PCI: pciehp: remove unused pciehp_get_max_lnk_width(), pciehp_get_cur_lnk_width() PCI: reorder __pci_assign_resource() (no change) PCI: fix truncation of resource size to 32 bits PCI: acpiphp: merge acpiphp_debug and debug PCI: acpiphp: remove unused res_lock sparc/PCI: replace pci_cfg_fake_ranges() with pci_read_bridge_bases() PCI: call final fixups hot-added devices PCI: move final fixups from __init to __devinit x86/PCI: move final fixups from __init to __devinit MIPS/PCI: move final fixups from __init to __devinit PCI: support sizing P2P bridge I/O windows with 1K granularity PCI: reimplement P2P bridge 1K I/O windows (Intel P64H2) PCI: disable MEM decoding while updating 64-bit MEM BARs PCI: leave MEM and IO decoding disabled during 64-bit BAR sizing, too PCI: never discard enable/suspend/resume_early/resume fixups PCI: release temporary reference in __nv_msi_ht_cap_quirk() PCI: restructure 'pci_do_fixups()' ...
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a7ba6de588a8..fb506137aaee 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -265,7 +265,7 @@ out:
265 * assign_requested_resources_sorted() - satisfy resource requests 265 * assign_requested_resources_sorted() - satisfy resource requests
266 * 266 *
267 * @head : head of the list tracking requests for resources 267 * @head : head of the list tracking requests for resources
268 * @failed_list : head of the list tracking requests that could 268 * @fail_head : head of the list tracking requests that could
269 * not be allocated 269 * not be allocated
270 * 270 *
271 * Satisfy resource requests of each element in the list. Add 271 * Satisfy resource requests of each element in the list. Add
@@ -404,8 +404,8 @@ void pci_setup_cardbus(struct pci_bus *bus)
404 struct resource *res; 404 struct resource *res;
405 struct pci_bus_region region; 405 struct pci_bus_region region;
406 406
407 dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", 407 dev_info(&bridge->dev, "CardBus bridge to %pR\n",
408 bus->secondary, bus->subordinate); 408 &bus->busn_res);
409 409
410 res = bus->resource[0]; 410 res = bus->resource[0];
411 pcibios_resource_to_bus(bridge, &region, res); 411 pcibios_resource_to_bus(bridge, &region, res);
@@ -469,16 +469,23 @@ static void pci_setup_bridge_io(struct pci_bus *bus)
469 struct pci_dev *bridge = bus->self; 469 struct pci_dev *bridge = bus->self;
470 struct resource *res; 470 struct resource *res;
471 struct pci_bus_region region; 471 struct pci_bus_region region;
472 unsigned long io_mask;
473 u8 io_base_lo, io_limit_lo;
472 u32 l, io_upper16; 474 u32 l, io_upper16;
473 475
476 io_mask = PCI_IO_RANGE_MASK;
477 if (bridge->io_window_1k)
478 io_mask = PCI_IO_1K_RANGE_MASK;
479
474 /* Set up the top and bottom of the PCI I/O segment for this bus. */ 480 /* Set up the top and bottom of the PCI I/O segment for this bus. */
475 res = bus->resource[0]; 481 res = bus->resource[0];
476 pcibios_resource_to_bus(bridge, &region, res); 482 pcibios_resource_to_bus(bridge, &region, res);
477 if (res->flags & IORESOURCE_IO) { 483 if (res->flags & IORESOURCE_IO) {
478 pci_read_config_dword(bridge, PCI_IO_BASE, &l); 484 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
479 l &= 0xffff0000; 485 l &= 0xffff0000;
480 l |= (region.start >> 8) & 0x00f0; 486 io_base_lo = (region.start >> 8) & io_mask;
481 l |= region.end & 0xf000; 487 io_limit_lo = (region.end >> 8) & io_mask;
488 l |= ((u32) io_limit_lo << 8) | io_base_lo;
482 /* Set up upper 16 bits of I/O base/limit. */ 489 /* Set up upper 16 bits of I/O base/limit. */
483 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); 490 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
484 dev_info(&bridge->dev, " bridge window %pR\n", res); 491 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)
553{ 560{
554 struct pci_dev *bridge = bus->self; 561 struct pci_dev *bridge = bus->self;
555 562
556 dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", 563 dev_info(&bridge->dev, "PCI bridge to %pR\n",
557 bus->secondary, bus->subordinate); 564 &bus->busn_res);
558 565
559 if (type & IORESOURCE_IO) 566 if (type & IORESOURCE_IO)
560 pci_setup_bridge_io(bus); 567 pci_setup_bridge_io(bus);
@@ -699,7 +706,7 @@ static resource_size_t calculate_memsize(resource_size_t size,
699 * @realloc_head : track the additional io window on this list 706 * @realloc_head : track the additional io window on this list
700 * 707 *
701 * Sizing the IO windows of the PCI-PCI bridge is trivial, 708 * Sizing the IO windows of the PCI-PCI bridge is trivial,
702 * since these windows have 4K granularity and the IO ranges 709 * since these windows have 1K or 4K granularity and the IO ranges
703 * of non-bridge PCI devices are limited to 256 bytes. 710 * of non-bridge PCI devices are limited to 256 bytes.
704 * We must be careful with the ISA aliasing though. 711 * We must be careful with the ISA aliasing though.
705 */ 712 */
@@ -710,10 +717,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
710 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); 717 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
711 unsigned long size = 0, size0 = 0, size1 = 0; 718 unsigned long size = 0, size0 = 0, size1 = 0;
712 resource_size_t children_add_size = 0; 719 resource_size_t children_add_size = 0;
720 resource_size_t min_align = 4096, align;
713 721
714 if (!b_res) 722 if (!b_res)
715 return; 723 return;
716 724
725 /*
726 * Per spec, I/O windows are 4K-aligned, but some bridges have an
727 * extension to support 1K alignment.
728 */
729 if (bus->self->io_window_1k)
730 min_align = 1024;
717 list_for_each_entry(dev, &bus->devices, bus_list) { 731 list_for_each_entry(dev, &bus->devices, bus_list) {
718 int i; 732 int i;
719 733
@@ -731,34 +745,43 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
731 else 745 else
732 size1 += r_size; 746 size1 += r_size;
733 747
748 align = pci_resource_alignment(dev, r);
749 if (align > min_align)
750 min_align = align;
751
734 if (realloc_head) 752 if (realloc_head)
735 children_add_size += get_res_add_size(realloc_head, r); 753 children_add_size += get_res_add_size(realloc_head, r);
736 } 754 }
737 } 755 }
756
757 if (min_align > 4096)
758 min_align = 4096;
759
738 size0 = calculate_iosize(size, min_size, size1, 760 size0 = calculate_iosize(size, min_size, size1,
739 resource_size(b_res), 4096); 761 resource_size(b_res), min_align);
740 if (children_add_size > add_size) 762 if (children_add_size > add_size)
741 add_size = children_add_size; 763 add_size = children_add_size;
742 size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : 764 size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
743 calculate_iosize(size, min_size, add_size + size1, 765 calculate_iosize(size, min_size, add_size + size1,
744 resource_size(b_res), 4096); 766 resource_size(b_res), min_align);
745 if (!size0 && !size1) { 767 if (!size0 && !size1) {
746 if (b_res->start || b_res->end) 768 if (b_res->start || b_res->end)
747 dev_info(&bus->self->dev, "disabling bridge window " 769 dev_info(&bus->self->dev, "disabling bridge window "
748 "%pR to [bus %02x-%02x] (unused)\n", b_res, 770 "%pR to %pR (unused)\n", b_res,
749 bus->secondary, bus->subordinate); 771 &bus->busn_res);
750 b_res->flags = 0; 772 b_res->flags = 0;
751 return; 773 return;
752 } 774 }
753 /* Alignment of the IO window is always 4K */ 775
754 b_res->start = 4096; 776 b_res->start = min_align;
755 b_res->end = b_res->start + size0 - 1; 777 b_res->end = b_res->start + size0 - 1;
756 b_res->flags |= IORESOURCE_STARTALIGN; 778 b_res->flags |= IORESOURCE_STARTALIGN;
757 if (size1 > size0 && realloc_head) { 779 if (size1 > size0 && realloc_head) {
758 add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); 780 add_to_list(realloc_head, bus->self, b_res, size1-size0,
781 min_align);
759 dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " 782 dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
760 "%pR to [bus %02x-%02x] add_size %lx\n", b_res, 783 "%pR to %pR add_size %lx\n", b_res,
761 bus->secondary, bus->subordinate, size1-size0); 784 &bus->busn_res, size1-size0);
762 } 785 }
763} 786}
764 787
@@ -863,8 +886,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
863 if (!size0 && !size1) { 886 if (!size0 && !size1) {
864 if (b_res->start || b_res->end) 887 if (b_res->start || b_res->end)
865 dev_info(&bus->self->dev, "disabling bridge window " 888 dev_info(&bus->self->dev, "disabling bridge window "
866 "%pR to [bus %02x-%02x] (unused)\n", b_res, 889 "%pR to %pR (unused)\n", b_res,
867 bus->secondary, bus->subordinate); 890 &bus->busn_res);
868 b_res->flags = 0; 891 b_res->flags = 0;
869 return 1; 892 return 1;
870 } 893 }
@@ -874,8 +897,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
874 if (size1 > size0 && realloc_head) { 897 if (size1 > size0 && realloc_head) {
875 add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); 898 add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
876 dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " 899 dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
877 "%pR to [bus %02x-%02x] add_size %llx\n", b_res, 900 "%pR to %pR add_size %llx\n", b_res,
878 bus->secondary, bus->subordinate, (unsigned long long)size1-size0); 901 &bus->busn_res, (unsigned long long)size1-size0);
879 } 902 }
880 return 1; 903 return 1;
881} 904}