aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 14:15:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 14:15:26 -0400
commit37577505ec6e67d550aa5fb452c7b45a093cc7f3 (patch)
tree44f22364883679308c51cae6ebb8d164ad3aa5d1 /arch/ia64/sn/kernel
parent04bbc8e1f68cf4c1aac8024d6aea1a24757e8a5a (diff)
parentc4cbf6b96100bbcd5da6e38b3334901b2eaa25bf (diff)
Merge tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull ia64 IOH hotplug fixes from Tony Luck: "Series to fix IOH hotplug in ia64" * tag 'please-pull-root_bus_hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux: PCI: Replace printks with appropriate pr_*() PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource PCI/IA64: Add host bridge resource release for _CRS path PCI/IA64: fix memleak for create pci root bus fail PCI/IA64: Allocate pci_root_info instead of using stack PCI/IA64: embed pci hostbridge resources into pci_root_info PCI/IA64: SN: use normal resource instead of pci_window PCI/IA64: SN: remove sn_pci_window_fixup()
Diffstat (limited to 'arch/ia64/sn/kernel')
-rw-r--r--arch/ia64/sn/kernel/io_init.c109
1 files changed, 26 insertions, 83 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 238e2c511d94..2b00adedc45e 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -118,76 +118,26 @@ static void __init sn_fixup_ionodes(void)
118} 118}
119 119
120/* 120/*
121 * sn_pci_legacy_window_fixup - Create PCI controller windows for 121 * sn_pci_legacy_window_fixup - Setup PCI resources for
122 * legacy IO and MEM space. This needs to 122 * legacy IO and MEM space. This needs to
123 * be done here, as the PROM does not have 123 * be done here, as the PROM does not have
124 * ACPI support defining the root buses 124 * ACPI support defining the root buses
125 * and their resources (_CRS), 125 * and their resources (_CRS),
126 */ 126 */
127static void 127static void
128sn_legacy_pci_window_fixup(struct pci_controller *controller, 128sn_legacy_pci_window_fixup(struct resource *res,
129 u64 legacy_io, u64 legacy_mem) 129 u64 legacy_io, u64 legacy_mem)
130{ 130{
131 controller->window = kcalloc(2, sizeof(struct pci_window), 131 res[0].name = "legacy_io";
132 GFP_KERNEL); 132 res[0].flags = IORESOURCE_IO;
133 BUG_ON(controller->window == NULL); 133 res[0].start = legacy_io;
134 controller->window[0].offset = legacy_io; 134 res[0].end = res[0].start + 0xffff;
135 controller->window[0].resource.name = "legacy_io"; 135 res[0].parent = &ioport_resource;
136 controller->window[0].resource.flags = IORESOURCE_IO; 136 res[1].name = "legacy_mem";
137 controller->window[0].resource.start = legacy_io; 137 res[1].flags = IORESOURCE_MEM;
138 controller->window[0].resource.end = 138 res[1].start = legacy_mem;
139 controller->window[0].resource.start + 0xffff; 139 res[1].end = res[1].start + (1024 * 1024) - 1;
140 controller->window[0].resource.parent = &ioport_resource; 140 res[1].parent = &iomem_resource;
141 controller->window[1].offset = legacy_mem;
142 controller->window[1].resource.name = "legacy_mem";
143 controller->window[1].resource.flags = IORESOURCE_MEM;
144 controller->window[1].resource.start = legacy_mem;
145 controller->window[1].resource.end =
146 controller->window[1].resource.start + (1024 * 1024) - 1;
147 controller->window[1].resource.parent = &iomem_resource;
148 controller->windows = 2;
149}
150
151/*
152 * sn_pci_window_fixup() - Create a pci_window for each device resource.
153 * It will setup pci_windows for use by
154 * pcibios_bus_to_resource(), pcibios_resource_to_bus(),
155 * etc.
156 */
157static void
158sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
159 s64 * pci_addrs)
160{
161 struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
162 unsigned int i;
163 unsigned int idx;
164 unsigned int new_count;
165 struct pci_window *new_window;
166
167 if (count == 0)
168 return;
169 idx = controller->windows;
170 new_count = controller->windows + count;
171 new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
172 BUG_ON(new_window == NULL);
173 if (controller->window) {
174 memcpy(new_window, controller->window,
175 sizeof(struct pci_window) * controller->windows);
176 kfree(controller->window);
177 }
178
179 /* Setup a pci_window for each device resource. */
180 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
181 if (pci_addrs[i] == -1)
182 continue;
183
184 new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
185 new_window[idx].resource = dev->resource[i];
186 idx++;
187 }
188
189 controller->windows = new_count;
190 controller->window = new_window;
191} 141}
192 142
193/* 143/*
@@ -199,9 +149,7 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
199void 149void
200sn_io_slot_fixup(struct pci_dev *dev) 150sn_io_slot_fixup(struct pci_dev *dev)
201{ 151{
202 unsigned int count = 0;
203 int idx; 152 int idx;
204 s64 pci_addrs[PCI_ROM_RESOURCE + 1];
205 unsigned long addr, end, size, start; 153 unsigned long addr, end, size, start;
206 struct pcidev_info *pcidev_info; 154 struct pcidev_info *pcidev_info;
207 struct sn_irq_info *sn_irq_info; 155 struct sn_irq_info *sn_irq_info;
@@ -229,7 +177,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
229 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { 177 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
230 178
231 if (!pcidev_info->pdi_pio_mapped_addr[idx]) { 179 if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
232 pci_addrs[idx] = -1;
233 continue; 180 continue;
234 } 181 }
235 182
@@ -237,11 +184,8 @@ sn_io_slot_fixup(struct pci_dev *dev)
237 end = dev->resource[idx].end; 184 end = dev->resource[idx].end;
238 size = end - start; 185 size = end - start;
239 if (size == 0) { 186 if (size == 0) {
240 pci_addrs[idx] = -1;
241 continue; 187 continue;
242 } 188 }
243 pci_addrs[idx] = start;
244 count++;
245 addr = pcidev_info->pdi_pio_mapped_addr[idx]; 189 addr = pcidev_info->pdi_pio_mapped_addr[idx];
246 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; 190 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
247 dev->resource[idx].start = addr; 191 dev->resource[idx].start = addr;
@@ -276,11 +220,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
276 IORESOURCE_ROM_BIOS_COPY; 220 IORESOURCE_ROM_BIOS_COPY;
277 } 221 }
278 } 222 }
279 /* Create a pci_window in the pci_controller struct for
280 * each device resource.
281 */
282 if (count > 0)
283 sn_pci_window_fixup(dev, count, pci_addrs);
284 223
285 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); 224 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
286} 225}
@@ -297,8 +236,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
297 s64 status = 0; 236 s64 status = 0;
298 struct pci_controller *controller; 237 struct pci_controller *controller;
299 struct pcibus_bussoft *prom_bussoft_ptr; 238 struct pcibus_bussoft *prom_bussoft_ptr;
239 struct resource *res;
300 LIST_HEAD(resources); 240 LIST_HEAD(resources);
301 int i;
302 241
303 status = sal_get_pcibus_info((u64) segment, (u64) busnum, 242 status = sal_get_pcibus_info((u64) segment, (u64) busnum,
304 (u64) ia64_tpa(&prom_bussoft_ptr)); 243 (u64) ia64_tpa(&prom_bussoft_ptr));
@@ -310,19 +249,23 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
310 BUG_ON(!controller); 249 BUG_ON(!controller);
311 controller->segment = segment; 250 controller->segment = segment;
312 251
252 res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
253 BUG_ON(!res);
254
313 /* 255 /*
314 * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). 256 * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup().
315 * (platform_data will be overwritten later in sn_common_bus_fixup()) 257 * (platform_data will be overwritten later in sn_common_bus_fixup())
316 */ 258 */
317 controller->platform_data = prom_bussoft_ptr; 259 controller->platform_data = prom_bussoft_ptr;
318 260
319 sn_legacy_pci_window_fixup(controller, 261 sn_legacy_pci_window_fixup(res,
320 prom_bussoft_ptr->bs_legacy_io, 262 prom_bussoft_ptr->bs_legacy_io,
321 prom_bussoft_ptr->bs_legacy_mem); 263 prom_bussoft_ptr->bs_legacy_mem);
322 for (i = 0; i < controller->windows; i++) 264 pci_add_resource_offset(&resources, &res[0],
323 pci_add_resource_offset(&resources, 265 prom_bussoft_ptr->bs_legacy_io);
324 &controller->window[i].resource, 266 pci_add_resource_offset(&resources, &res[1],
325 controller->window[i].offset); 267 prom_bussoft_ptr->bs_legacy_mem);
268
326 bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, 269 bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
327 &resources); 270 &resources);
328 if (bus == NULL) 271 if (bus == NULL)
@@ -333,7 +276,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
333 return; 276 return;
334 277
335error_return: 278error_return:
336 279 kfree(res);
337 kfree(controller); 280 kfree(controller);
338 return; 281 return;
339} 282}