aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/pci.c')
-rw-r--r--arch/sparc64/kernel/pci.c133
1 files changed, 5 insertions, 128 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9c17591c2a79..2ff7c32ab0ce 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -359,140 +359,17 @@ void pcibios_fixup_bus(struct pci_bus *pbus)
359 pbus->resource[1] = &pbm->mem_space; 359 pbus->resource[1] = &pbm->mem_space;
360} 360}
361 361
362int pci_claim_resource(struct pci_dev *pdev, int resource) 362struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r)
363{ 363{
364 struct pci_pbm_info *pbm = pdev->bus->sysdata; 364 struct pci_pbm_info *pbm = pdev->bus->sysdata;
365 struct resource *res = &pdev->resource[resource]; 365 struct resource *root = NULL;
366 struct resource *root;
367
368 if (!pbm)
369 return -EINVAL;
370 366
371 if (res->flags & IORESOURCE_IO) 367 if (r->flags & IORESOURCE_IO)
372 root = &pbm->io_space; 368 root = &pbm->io_space;
373 else 369 if (r->flags & IORESOURCE_MEM)
374 root = &pbm->mem_space; 370 root = &pbm->mem_space;
375 371
376 pbm->parent->resource_adjust(pdev, res, root); 372 return root;
377
378 return request_resource(root, res);
379}
380
381/*
382 * Given the PCI bus a device resides on, try to
383 * find an acceptable resource allocation for a
384 * specific device resource..
385 */
386static int pci_assign_bus_resource(const struct pci_bus *bus,
387 struct pci_dev *dev,
388 struct resource *res,
389 unsigned long size,
390 unsigned long min,
391 int resno)
392{
393 unsigned int type_mask;
394 int i;
395
396 type_mask = IORESOURCE_IO | IORESOURCE_MEM;
397 for (i = 0 ; i < 4; i++) {
398 struct resource *r = bus->resource[i];
399 if (!r)
400 continue;
401
402 /* type_mask must match */
403 if ((res->flags ^ r->flags) & type_mask)
404 continue;
405
406 /* Ok, try it out.. */
407 if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0)
408 continue;
409
410 /* PCI config space updated by caller. */
411 return 0;
412 }
413 return -EBUSY;
414}
415
416void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
417{
418 /* Not implemented for sparc64... */
419 BUG();
420}
421
422int pci_assign_resource(struct pci_dev *pdev, int resource)
423{
424 struct pcidev_cookie *pcp = pdev->sysdata;
425 struct pci_pbm_info *pbm = pcp->pbm;
426 struct resource *res = &pdev->resource[resource];
427 unsigned long min, size;
428 int err;
429
430 if (res->flags & IORESOURCE_IO)
431 min = pbm->io_space.start + 0x400UL;
432 else
433 min = pbm->mem_space.start;
434
435 size = res->end - res->start + 1;
436
437 err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource);
438
439 if (err < 0) {
440 printk("PCI: Failed to allocate resource %d for %s\n",
441 resource, pci_name(pdev));
442 } else {
443 /* Update PCI config space. */
444 pbm->parent->base_address_update(pdev, resource);
445 }
446
447 return err;
448}
449
450/* Sort resources by alignment */
451void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
452{
453 int i;
454
455 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
456 struct resource *r;
457 struct resource_list *list, *tmp;
458 unsigned long r_align;
459
460 r = &dev->resource[i];
461 r_align = r->end - r->start;
462
463 if (!(r->flags) || r->parent)
464 continue;
465 if (!r_align) {
466 printk(KERN_WARNING "PCI: Ignore bogus resource %d "
467 "[%lx:%lx] of %s\n",
468 i, r->start, r->end, pci_name(dev));
469 continue;
470 }
471 r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
472 for (list = head; ; list = list->next) {
473 unsigned long align = 0;
474 struct resource_list *ln = list->next;
475 int idx;
476
477 if (ln) {
478 idx = ln->res - &ln->dev->resource[0];
479 align = (idx < PCI_BRIDGE_RESOURCES) ?
480 ln->res->end - ln->res->start + 1 :
481 ln->res->start;
482 }
483 if (r_align > align) {
484 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
485 if (!tmp)
486 panic("pdev_sort_resources(): "
487 "kmalloc() failed!\n");
488 tmp->next = ln;
489 tmp->res = r;
490 tmp->dev = dev;
491 list->next = tmp;
492 break;
493 }
494 }
495 }
496} 373}
497 374
498void pcibios_update_irq(struct pci_dev *pdev, int irq) 375void pcibios_update_irq(struct pci_dev *pdev, int irq)