]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.arch/ppc-pcibios_allocate_bus_resources.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / ppc-pcibios_allocate_bus_resources.patch
1 Subject: Fix DLPAR
2 From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
3 References: 439491
4
5 Signed-off-by: Olaf Hering <olh@suse.de>
6 ---
7 arch/powerpc/include/asm/pci.h | 2
8 arch/powerpc/kernel/pci-common.c | 110 ++++++++++++++---------------
9 arch/powerpc/platforms/pseries/pci_dlpar.c | 2
10 3 files changed, 59 insertions(+), 55 deletions(-)
11
12 --- a/arch/powerpc/include/asm/pci.h
13 +++ b/arch/powerpc/include/asm/pci.h
14 @@ -196,6 +196,8 @@ extern void pcibios_setup_new_device(str
15
16 extern void pcibios_claim_one_bus(struct pci_bus *b);
17
18 +extern void pcibios_allocate_bus_resources(struct pci_bus *bus);
19 +
20 extern void pcibios_resource_survey(void);
21
22 extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
23 --- a/arch/powerpc/kernel/pci-common.c
24 +++ b/arch/powerpc/kernel/pci-common.c
25 @@ -986,69 +986,66 @@ static int __init reparent_resources(str
26 * as well.
27 */
28
29 -static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
30 +void pcibios_allocate_bus_resources(struct pci_bus *bus)
31 {
32 - struct pci_bus *bus;
33 + struct pci_bus *b;
34 int i;
35 struct resource *res, *pr;
36
37 - /* Depth-First Search on bus tree */
38 - list_for_each_entry(bus, bus_list, node) {
39 - for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
40 - if ((res = bus->resource[i]) == NULL || !res->flags
41 - || res->start > res->end)
42 - continue;
43 - if (bus->parent == NULL)
44 - pr = (res->flags & IORESOURCE_IO) ?
45 - &ioport_resource : &iomem_resource;
46 - else {
47 - /* Don't bother with non-root busses when
48 - * re-assigning all resources. We clear the
49 - * resource flags as if they were colliding
50 - * and as such ensure proper re-allocation
51 - * later.
52 + for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
53 + if ((res = bus->resource[i]) == NULL || !res->flags
54 + || res->start > res->end)
55 + continue;
56 + if (bus->parent == NULL)
57 + pr = (res->flags & IORESOURCE_IO) ?
58 + &ioport_resource : &iomem_resource;
59 + else {
60 + /* Don't bother with non-root busses when
61 + * re-assigning all resources. We clear the
62 + * resource flags as if they were colliding
63 + * and as such ensure proper re-allocation
64 + * later.
65 + */
66 + if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
67 + goto clear_resource;
68 + pr = pci_find_parent_resource(bus->self, res);
69 + if (pr == res) {
70 + /* this happens when the generic PCI
71 + * code (wrongly) decides that this
72 + * bridge is transparent -- paulus
73 */
74 - if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
75 - goto clear_resource;
76 - pr = pci_find_parent_resource(bus->self, res);
77 - if (pr == res) {
78 - /* this happens when the generic PCI
79 - * code (wrongly) decides that this
80 - * bridge is transparent -- paulus
81 - */
82 - continue;
83 - }
84 + continue;
85 }
86 + }
87
88 - DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
89 - "[0x%x], parent %p (%s)\n",
90 - bus->self ? pci_name(bus->self) : "PHB",
91 - bus->number, i,
92 - (unsigned long long)res->start,
93 - (unsigned long long)res->end,
94 - (unsigned int)res->flags,
95 - pr, (pr && pr->name) ? pr->name : "nil");
96 -
97 - if (pr && !(pr->flags & IORESOURCE_UNSET)) {
98 - if (request_resource(pr, res) == 0)
99 - continue;
100 - /*
101 - * Must be a conflict with an existing entry.
102 - * Move that entry (or entries) under the
103 - * bridge resource and try again.
104 - */
105 - if (reparent_resources(pr, res) == 0)
106 - continue;
107 - }
108 - printk(KERN_WARNING
109 - "PCI: Cannot allocate resource region "
110 - "%d of PCI bridge %d, will remap\n",
111 - i, bus->number);
112 -clear_resource:
113 - res->flags = 0;
114 + DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
115 + "[0x%x], parent %p (%s)\n",
116 + bus->self ? pci_name(bus->self) : "PHB",
117 + bus->number, i,
118 + (unsigned long long)res->start,
119 + (unsigned long long)res->end,
120 + (unsigned int)res->flags,
121 + pr, (pr && pr->name) ? pr->name : "nil");
122 +
123 + if (pr && !(pr->flags & IORESOURCE_UNSET)) {
124 + if (request_resource(pr, res) == 0)
125 + continue;
126 + /*
127 + * Must be a conflict with an existing entry.
128 + * Move that entry (or entries) under the
129 + * bridge resource and try again.
130 + */
131 + if (reparent_resources(pr, res) == 0)
132 + continue;
133 }
134 - pcibios_allocate_bus_resources(&bus->children);
135 + printk(KERN_WARNING "PCI: Cannot allocate resource region "
136 + "%d of PCI bridge %d, will remap\n", i, bus->number);
137 +clear_resource:
138 + res->flags = 0;
139 }
140 +
141 + list_for_each_entry(b, &bus->children, node)
142 + pcibios_allocate_bus_resources(b);
143 }
144
145 static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
146 @@ -1119,10 +1116,13 @@ static void __init pcibios_allocate_reso
147
148 void __init pcibios_resource_survey(void)
149 {
150 + struct pci_bus *b;
151 +
152 /* Allocate and assign resources. If we re-assign everything, then
153 * we skip the allocate phase
154 */
155 - pcibios_allocate_bus_resources(&pci_root_buses);
156 + list_for_each_entry(b, &pci_root_buses, node)
157 + pcibios_allocate_bus_resources(b);
158
159 if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
160 pcibios_allocate_resources(0);
161 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c
162 +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
163 @@ -189,6 +189,7 @@ struct pci_controller * __devinit init_p
164 {
165 struct pci_controller *phb;
166 int primary;
167 + struct pci_bus *b;
168
169 primary = list_empty(&hose_list);
170 phb = pcibios_alloc_controller(dn);
171 @@ -203,6 +204,7 @@ struct pci_controller * __devinit init_p
172 eeh_add_device_tree_early(dn);
173
174 scan_phb(phb);
175 + pcibios_allocate_bus_resources(phb->bus);
176 pcibios_fixup_new_pci_devices(phb->bus);
177 pci_bus_add_devices(phb->bus);
178 eeh_add_device_tree_late(phb->bus);