diff options
author | Ram Pai <linuxram@us.ibm.com> | 2011-07-25 16:08:41 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-08-01 14:50:40 -0400 |
commit | 0a2daa1cf35004f5adbf4138555cc5669abf3a3e (patch) | |
tree | 035bd37e33f7e95f226d9e46e173c043f0fbe018 /drivers/pci | |
parent | 2aceefcbd5a73059e5f52831817ec277e987440d (diff) |
PCI: make cardbus-bridge resources optional
Allocate resources to cardbus bridge only after all other genuine
resources requests are satisfied. Dont retry if resource allocation
for cardbus-bridges fail.
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci.h | 4 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 41 |
2 files changed, 36 insertions, 9 deletions
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index c8cee764b0de..b74084e9ca12 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -283,6 +283,8 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) | |||
283 | 283 | ||
284 | #endif /* CONFIG_PCI_IOV */ | 284 | #endif /* CONFIG_PCI_IOV */ |
285 | 285 | ||
286 | extern unsigned long pci_cardbus_resource_alignment(struct resource *); | ||
287 | |||
286 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | 288 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, |
287 | struct resource *res) | 289 | struct resource *res) |
288 | { | 290 | { |
@@ -292,6 +294,8 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | |||
292 | if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) | 294 | if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) |
293 | return pci_sriov_resource_alignment(dev, resno); | 295 | return pci_sriov_resource_alignment(dev, resno); |
294 | #endif | 296 | #endif |
297 | if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS) | ||
298 | return pci_cardbus_resource_alignment(res); | ||
295 | return resource_alignment(res); | 299 | return resource_alignment(res); |
296 | } | 300 | } |
297 | 301 | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1c19b9f4019a..29e7cc73537c 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -164,6 +164,7 @@ static void adjust_resources_sorted(struct resource_list_x *add_head, | |||
164 | idx = res - &list->dev->resource[0]; | 164 | idx = res - &list->dev->resource[0]; |
165 | add_size=list->add_size; | 165 | add_size=list->add_size; |
166 | if (!resource_size(res)) { | 166 | if (!resource_size(res)) { |
167 | res->start = list->start; | ||
167 | res->end = res->start + add_size - 1; | 168 | res->end = res->start + add_size - 1; |
168 | if(pci_assign_resource(list->dev, idx)) | 169 | if(pci_assign_resource(list->dev, idx)) |
169 | reset_resource(res); | 170 | reset_resource(res); |
@@ -223,7 +224,7 @@ static void __assign_resources_sorted(struct resource_list *head, | |||
223 | /* Satisfy the must-have resource requests */ | 224 | /* Satisfy the must-have resource requests */ |
224 | assign_requested_resources_sorted(head, fail_head); | 225 | assign_requested_resources_sorted(head, fail_head); |
225 | 226 | ||
226 | /* Try to satisfy any additional nice-to-have resource | 227 | /* Try to satisfy any additional optional resource |
227 | requests */ | 228 | requests */ |
228 | if (add_head) | 229 | if (add_head) |
229 | adjust_resources_sorted(add_head, head); | 230 | adjust_resources_sorted(add_head, head); |
@@ -678,7 +679,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
678 | if (add_head && i >= PCI_IOV_RESOURCES && | 679 | if (add_head && i >= PCI_IOV_RESOURCES && |
679 | i <= PCI_IOV_RESOURCE_END) { | 680 | i <= PCI_IOV_RESOURCE_END) { |
680 | r->end = r->start - 1; | 681 | r->end = r->start - 1; |
681 | add_to_list(add_head, dev, r, r_size, 1); | 682 | add_to_list(add_head, dev, r, r_size, 0/* dont' care */); |
682 | children_add_size += r_size; | 683 | children_add_size += r_size; |
683 | continue; | 684 | continue; |
684 | } | 685 | } |
@@ -743,7 +744,17 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
743 | return 1; | 744 | return 1; |
744 | } | 745 | } |
745 | 746 | ||
746 | static void pci_bus_size_cardbus(struct pci_bus *bus) | 747 | unsigned long pci_cardbus_resource_alignment(struct resource *res) |
748 | { | ||
749 | if (res->flags & IORESOURCE_IO) | ||
750 | return pci_cardbus_io_size; | ||
751 | if (res->flags & IORESOURCE_MEM) | ||
752 | return pci_cardbus_mem_size; | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static void pci_bus_size_cardbus(struct pci_bus *bus, | ||
757 | struct resource_list_x *add_head) | ||
747 | { | 758 | { |
748 | struct pci_dev *bridge = bus->self; | 759 | struct pci_dev *bridge = bus->self; |
749 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | 760 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; |
@@ -754,12 +765,14 @@ static void pci_bus_size_cardbus(struct pci_bus *bus) | |||
754 | * a fixed amount of bus space for CardBus bridges. | 765 | * a fixed amount of bus space for CardBus bridges. |
755 | */ | 766 | */ |
756 | b_res[0].start = 0; | 767 | b_res[0].start = 0; |
757 | b_res[0].end = pci_cardbus_io_size - 1; | ||
758 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 768 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; |
769 | if (add_head) | ||
770 | add_to_list(add_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */); | ||
759 | 771 | ||
760 | b_res[1].start = 0; | 772 | b_res[1].start = 0; |
761 | b_res[1].end = pci_cardbus_io_size - 1; | ||
762 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 773 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; |
774 | if (add_head) | ||
775 | add_to_list(add_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */); | ||
763 | 776 | ||
764 | /* | 777 | /* |
765 | * Check whether prefetchable memory is supported | 778 | * Check whether prefetchable memory is supported |
@@ -779,17 +792,27 @@ static void pci_bus_size_cardbus(struct pci_bus *bus) | |||
779 | */ | 792 | */ |
780 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { | 793 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { |
781 | b_res[2].start = 0; | 794 | b_res[2].start = 0; |
782 | b_res[2].end = pci_cardbus_mem_size - 1; | ||
783 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; | 795 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; |
796 | if (add_head) | ||
797 | add_to_list(add_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */); | ||
784 | 798 | ||
785 | b_res[3].start = 0; | 799 | b_res[3].start = 0; |
786 | b_res[3].end = pci_cardbus_mem_size - 1; | ||
787 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 800 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; |
801 | if (add_head) | ||
802 | add_to_list(add_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */); | ||
788 | } else { | 803 | } else { |
789 | b_res[3].start = 0; | 804 | b_res[3].start = 0; |
790 | b_res[3].end = pci_cardbus_mem_size * 2 - 1; | ||
791 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 805 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; |
806 | if (add_head) | ||
807 | add_to_list(add_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */); | ||
792 | } | 808 | } |
809 | |||
810 | /* set the size of the resource to zero, so that the resource does not | ||
811 | * get assigned during required-resource allocation cycle but gets assigned | ||
812 | * during the optional-resource allocation cycle. | ||
813 | */ | ||
814 | b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; | ||
815 | b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; | ||
793 | } | 816 | } |
794 | 817 | ||
795 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 818 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
@@ -806,7 +829,7 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
806 | 829 | ||
807 | switch (dev->class >> 8) { | 830 | switch (dev->class >> 8) { |
808 | case PCI_CLASS_BRIDGE_CARDBUS: | 831 | case PCI_CLASS_BRIDGE_CARDBUS: |
809 | pci_bus_size_cardbus(b); | 832 | pci_bus_size_cardbus(b, add_head); |
810 | break; | 833 | break; |
811 | 834 | ||
812 | case PCI_CLASS_BRIDGE_PCI: | 835 | case PCI_CLASS_BRIDGE_PCI: |