diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-10 02:54:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-11 02:07:41 -0400 |
commit | d3ae4b5bc7186a53731d35187ad4ba3bca147cf6 (patch) | |
tree | 53fbab0e70a170a3f6576e44e0b65fdbffe33258 /arch/sparc64/kernel/pci_fire.c | |
parent | ab138c031f72f6d030afa1a06a3a537e85ae843e (diff) |
sparc64: Get rid of pci_controller_info.
It is just used as a parent to encapsulate two PBM objects.
But that layout is only really relevant and necessary for
psycho PCI controllers, which unlike all the others share
a single IOMMU instance between sibling PCI busses.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_fire.c')
-rw-r--r-- | arch/sparc64/kernel/pci_fire.c | 55 |
1 files changed, 17 insertions, 38 deletions
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 1b44153f9077..b538bfb0a47a 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c | |||
@@ -431,22 +431,13 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) | |||
431 | fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); | 431 | fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); |
432 | } | 432 | } |
433 | 433 | ||
434 | static int __init pci_fire_pbm_init(struct pci_controller_info *p, | 434 | static int __init pci_fire_pbm_init(struct pci_pbm_info *pbm, |
435 | struct of_device *op, u32 portid) | 435 | struct of_device *op, u32 portid) |
436 | { | 436 | { |
437 | const struct linux_prom64_registers *regs; | 437 | const struct linux_prom64_registers *regs; |
438 | struct device_node *dp = op->node; | 438 | struct device_node *dp = op->node; |
439 | struct pci_pbm_info *pbm; | ||
440 | int err; | 439 | int err; |
441 | 440 | ||
442 | if ((portid & 1) == 0) | ||
443 | pbm = &p->pbm_A; | ||
444 | else | ||
445 | pbm = &p->pbm_B; | ||
446 | |||
447 | pbm->next = pci_pbm_root; | ||
448 | pci_pbm_root = pbm; | ||
449 | |||
450 | pbm->numa_node = -1; | 441 | pbm->numa_node = -1; |
451 | 442 | ||
452 | pbm->pci_ops = &sun4u_pci_ops; | 443 | pbm->pci_ops = &sun4u_pci_ops; |
@@ -455,7 +446,6 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, | |||
455 | pbm->index = pci_num_pbms++; | 446 | pbm->index = pci_num_pbms++; |
456 | 447 | ||
457 | pbm->portid = portid; | 448 | pbm->portid = portid; |
458 | pbm->parent = p; | ||
459 | pbm->prom_node = dp; | 449 | pbm->prom_node = dp; |
460 | pbm->name = dp->full_name; | 450 | pbm->name = dp->full_name; |
461 | 451 | ||
@@ -481,13 +471,9 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, | |||
481 | 471 | ||
482 | /* XXX register error interrupt handlers XXX */ | 472 | /* XXX register error interrupt handlers XXX */ |
483 | 473 | ||
484 | return 0; | 474 | pbm->next = pci_pbm_root; |
485 | } | 475 | pci_pbm_root = pbm; |
486 | 476 | ||
487 | static inline int portid_compare(u32 x, u32 y) | ||
488 | { | ||
489 | if (x == (y ^ 1)) | ||
490 | return 1; | ||
491 | return 0; | 477 | return 0; |
492 | } | 478 | } |
493 | 479 | ||
@@ -495,48 +481,41 @@ static int __devinit fire_probe(struct of_device *op, | |||
495 | const struct of_device_id *match) | 481 | const struct of_device_id *match) |
496 | { | 482 | { |
497 | struct device_node *dp = op->node; | 483 | struct device_node *dp = op->node; |
498 | struct pci_controller_info *p; | ||
499 | struct pci_pbm_info *pbm; | 484 | struct pci_pbm_info *pbm; |
500 | struct iommu *iommu; | 485 | struct iommu *iommu; |
501 | u32 portid; | 486 | u32 portid; |
502 | int err; | 487 | int err; |
503 | 488 | ||
504 | portid = of_getintprop_default(dp, "portid", 0xff); | 489 | portid = of_getintprop_default(dp, "portid", 0xff); |
505 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | ||
506 | if (portid_compare(pbm->portid, portid)) | ||
507 | return pci_fire_pbm_init(pbm->parent, op, portid); | ||
508 | } | ||
509 | 490 | ||
510 | err = -ENOMEM; | 491 | err = -ENOMEM; |
511 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 492 | pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); |
512 | if (!p) { | 493 | if (!pbm) { |
513 | printk(KERN_ERR PFX "Cannot allocate controller info.\n"); | 494 | printk(KERN_ERR PFX "Cannot allocate pci_pbminfo.\n"); |
514 | goto out_err; | 495 | goto out_err; |
515 | } | 496 | } |
516 | 497 | ||
517 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 498 | iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); |
518 | if (!iommu) { | 499 | if (!iommu) { |
519 | printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); | 500 | printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); |
520 | goto out_free_controller; | 501 | goto out_free_controller; |
521 | } | 502 | } |
522 | 503 | ||
523 | p->pbm_A.iommu = iommu; | 504 | pbm->iommu = iommu; |
524 | 505 | ||
525 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 506 | err = pci_fire_pbm_init(pbm, op, portid); |
526 | if (!iommu) { | 507 | if (err) |
527 | printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); | 508 | goto out_free_iommu; |
528 | goto out_free_iommu_A; | ||
529 | } | ||
530 | 509 | ||
531 | p->pbm_B.iommu = iommu; | 510 | dev_set_drvdata(&op->dev, pbm); |
532 | 511 | ||
533 | return pci_fire_pbm_init(p, op, portid); | 512 | return 0; |
534 | 513 | ||
535 | out_free_iommu_A: | 514 | out_free_iommu: |
536 | kfree(p->pbm_A.iommu); | 515 | kfree(pbm->iommu); |
537 | 516 | ||
538 | out_free_controller: | 517 | out_free_controller: |
539 | kfree(p); | 518 | kfree(pbm); |
540 | 519 | ||
541 | out_err: | 520 | out_err: |
542 | return err; | 521 | return err; |