aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorRam Pai <linuxram@us.ibm.com>2011-07-25 16:08:41 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2011-08-01 14:50:40 -0400
commit0a2daa1cf35004f5adbf4138555cc5669abf3a3e (patch)
tree035bd37e33f7e95f226d9e46e173c043f0fbe018 /drivers/pci
parent2aceefcbd5a73059e5f52831817ec277e987440d (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.h4
-rw-r--r--drivers/pci/setup-bus.c41
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
286extern unsigned long pci_cardbus_resource_alignment(struct resource *);
287
286static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, 288static 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
746static void pci_bus_size_cardbus(struct pci_bus *bus) 747unsigned 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
756static 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
795void __ref __pci_bus_size_bridges(struct pci_bus *bus, 818void __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: