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 | |
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>
-rw-r--r-- | arch/sparc/include/asm/iommu_64.h | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_fire.c | 55 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_impl.h | 16 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 161 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 33 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 84 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 66 |
8 files changed, 181 insertions, 241 deletions
diff --git a/arch/sparc/include/asm/iommu_64.h b/arch/sparc/include/asm/iommu_64.h index d7b9afcba08b..caf798b56191 100644 --- a/arch/sparc/include/asm/iommu_64.h +++ b/arch/sparc/include/asm/iommu_64.h | |||
@@ -48,6 +48,9 @@ struct strbuf { | |||
48 | unsigned long strbuf_control; | 48 | unsigned long strbuf_control; |
49 | unsigned long strbuf_pflush; | 49 | unsigned long strbuf_pflush; |
50 | unsigned long strbuf_fsync; | 50 | unsigned long strbuf_fsync; |
51 | unsigned long strbuf_err_stat; | ||
52 | unsigned long strbuf_tag_diag; | ||
53 | unsigned long strbuf_line_diag; | ||
51 | unsigned long strbuf_ctxflush; | 54 | unsigned long strbuf_ctxflush; |
52 | unsigned long strbuf_ctxmatch_base; | 55 | unsigned long strbuf_ctxmatch_base; |
53 | unsigned long strbuf_flushflag_pa; | 56 | unsigned long strbuf_flushflag_pa; |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 8e18fdf32a60..3070f6faecca 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -977,14 +977,14 @@ int pcibus_to_node(struct pci_bus *pbus) | |||
977 | EXPORT_SYMBOL(pcibus_to_node); | 977 | EXPORT_SYMBOL(pcibus_to_node); |
978 | #endif | 978 | #endif |
979 | 979 | ||
980 | /* Return the domain nuber for this pci bus */ | 980 | /* Return the domain number for this pci bus */ |
981 | 981 | ||
982 | int pci_domain_nr(struct pci_bus *pbus) | 982 | int pci_domain_nr(struct pci_bus *pbus) |
983 | { | 983 | { |
984 | struct pci_pbm_info *pbm = pbus->sysdata; | 984 | struct pci_pbm_info *pbm = pbus->sysdata; |
985 | int ret; | 985 | int ret; |
986 | 986 | ||
987 | if (pbm == NULL || pbm->parent == NULL) { | 987 | if (!pbm) { |
988 | ret = -ENXIO; | 988 | ret = -ENXIO; |
989 | } else { | 989 | } else { |
990 | ret = pbm->index; | 990 | ret = pbm->index; |
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; |
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 4125f7513c69..4937ce903a88 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h | |||
@@ -56,15 +56,11 @@ struct sparc64_msiq_cookie { | |||
56 | }; | 56 | }; |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | struct pci_controller_info; | ||
60 | |||
61 | struct pci_pbm_info { | 59 | struct pci_pbm_info { |
62 | struct pci_pbm_info *next; | 60 | struct pci_pbm_info *next; |
61 | struct pci_pbm_info *sibling; | ||
63 | int index; | 62 | int index; |
64 | 63 | ||
65 | /* PCI controller we sit under. */ | ||
66 | struct pci_controller_info *parent; | ||
67 | |||
68 | /* Physical address base of controller registers. */ | 64 | /* Physical address base of controller registers. */ |
69 | unsigned long controller_regs; | 65 | unsigned long controller_regs; |
70 | 66 | ||
@@ -107,6 +103,10 @@ struct pci_pbm_info { | |||
107 | /* This will be 12 on PCI-E controllers, 8 elsewhere. */ | 103 | /* This will be 12 on PCI-E controllers, 8 elsewhere. */ |
108 | unsigned long config_space_reg_bits; | 104 | unsigned long config_space_reg_bits; |
109 | 105 | ||
106 | unsigned long pci_afsr; | ||
107 | unsigned long pci_afar; | ||
108 | unsigned long pci_csr; | ||
109 | |||
110 | /* State of 66MHz capabilities on this PBM. */ | 110 | /* State of 66MHz capabilities on this PBM. */ |
111 | int is_66mhz_capable; | 111 | int is_66mhz_capable; |
112 | int all_devs_66mhz; | 112 | int all_devs_66mhz; |
@@ -151,12 +151,6 @@ struct pci_pbm_info { | |||
151 | int numa_node; | 151 | int numa_node; |
152 | }; | 152 | }; |
153 | 153 | ||
154 | struct pci_controller_info { | ||
155 | /* The PCI bus modules controlled by us. */ | ||
156 | struct pci_pbm_info pbm_A; | ||
157 | struct pci_pbm_info pbm_B; | ||
158 | }; | ||
159 | |||
160 | extern struct pci_pbm_info *pci_pbm_root; | 154 | extern struct pci_pbm_info *pci_pbm_root; |
161 | 155 | ||
162 | extern int pci_num_pbms; | 156 | extern int pci_num_pbms; |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 0be850e6e580..70a7af092be2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -146,24 +146,16 @@ static unsigned long stc_error_buf[128]; | |||
146 | static unsigned long stc_tag_buf[16]; | 146 | static unsigned long stc_tag_buf[16]; |
147 | static unsigned long stc_line_buf[16]; | 147 | static unsigned long stc_line_buf[16]; |
148 | 148 | ||
149 | static void __psycho_check_one_stc(struct pci_pbm_info *pbm, | 149 | static void psycho_check_stc_error(struct pci_pbm_info *pbm) |
150 | int is_pbm_a) | ||
151 | { | 150 | { |
152 | struct strbuf *strbuf = &pbm->stc; | 151 | struct strbuf *strbuf = &pbm->stc; |
153 | unsigned long regbase = pbm->controller_regs; | ||
154 | unsigned long err_base, tag_base, line_base; | 152 | unsigned long err_base, tag_base, line_base; |
155 | u64 control; | 153 | u64 control; |
156 | int i; | 154 | int i; |
157 | 155 | ||
158 | if (is_pbm_a) { | 156 | err_base = strbuf->strbuf_err_stat; |
159 | err_base = regbase + PSYCHO_STC_ERR_A; | 157 | tag_base = strbuf->strbuf_tag_diag; |
160 | tag_base = regbase + PSYCHO_STC_TAG_A; | 158 | line_base = strbuf->strbuf_line_diag; |
161 | line_base = regbase + PSYCHO_STC_LINE_A; | ||
162 | } else { | ||
163 | err_base = regbase + PSYCHO_STC_ERR_B; | ||
164 | tag_base = regbase + PSYCHO_STC_TAG_B; | ||
165 | line_base = regbase + PSYCHO_STC_LINE_B; | ||
166 | } | ||
167 | 159 | ||
168 | spin_lock(&stc_buf_lock); | 160 | spin_lock(&stc_buf_lock); |
169 | 161 | ||
@@ -239,15 +231,6 @@ static void __psycho_check_one_stc(struct pci_pbm_info *pbm, | |||
239 | spin_unlock(&stc_buf_lock); | 231 | spin_unlock(&stc_buf_lock); |
240 | } | 232 | } |
241 | 233 | ||
242 | static void __psycho_check_stc_error(struct pci_pbm_info *pbm, | ||
243 | unsigned long afsr, | ||
244 | unsigned long afar, | ||
245 | enum psycho_error_type type) | ||
246 | { | ||
247 | __psycho_check_one_stc(pbm, | ||
248 | (pbm == &pbm->parent->pbm_A)); | ||
249 | } | ||
250 | |||
251 | /* When an Uncorrectable Error or a PCI Error happens, we | 234 | /* When an Uncorrectable Error or a PCI Error happens, we |
252 | * interrogate the IOMMU state to see if it is the cause. | 235 | * interrogate the IOMMU state to see if it is the cause. |
253 | */ | 236 | */ |
@@ -386,7 +369,7 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, | |||
386 | (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); | 369 | (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); |
387 | } | 370 | } |
388 | } | 371 | } |
389 | __psycho_check_stc_error(pbm, afsr, afar, type); | 372 | psycho_check_stc_error(pbm); |
390 | spin_unlock_irqrestore(&iommu->lock, flags); | 373 | spin_unlock_irqrestore(&iommu->lock, flags); |
391 | } | 374 | } |
392 | 375 | ||
@@ -412,7 +395,6 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, | |||
412 | static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | 395 | static irqreturn_t psycho_ue_intr(int irq, void *dev_id) |
413 | { | 396 | { |
414 | struct pci_pbm_info *pbm = dev_id; | 397 | struct pci_pbm_info *pbm = dev_id; |
415 | struct pci_controller_info *p = pbm->parent; | ||
416 | unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; | 398 | unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; |
417 | unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; | 399 | unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; |
418 | unsigned long afsr, afar, error_bits; | 400 | unsigned long afsr, afar, error_bits; |
@@ -465,8 +447,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | |||
465 | printk("]\n"); | 447 | printk("]\n"); |
466 | 448 | ||
467 | /* Interrogate both IOMMUs for error status. */ | 449 | /* Interrogate both IOMMUs for error status. */ |
468 | psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR); | 450 | psycho_check_iommu_error(pbm, afsr, afar, UE_ERR); |
469 | psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR); | 451 | if (pbm->sibling) |
452 | psycho_check_iommu_error(pbm->sibling, afsr, afar, UE_ERR); | ||
470 | 453 | ||
471 | return IRQ_HANDLED; | 454 | return IRQ_HANDLED; |
472 | } | 455 | } |
@@ -573,23 +556,18 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) | |||
573 | #define PSYCHO_PCI_AFAR_A 0x2018UL | 556 | #define PSYCHO_PCI_AFAR_A 0x2018UL |
574 | #define PSYCHO_PCI_AFAR_B 0x4018UL | 557 | #define PSYCHO_PCI_AFAR_B 0x4018UL |
575 | 558 | ||
576 | static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm_a) | 559 | static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm) |
577 | { | 560 | { |
578 | unsigned long csr_reg, csr, csr_error_bits; | 561 | unsigned long csr, csr_error_bits; |
579 | irqreturn_t ret = IRQ_NONE; | 562 | irqreturn_t ret = IRQ_NONE; |
580 | u16 stat; | 563 | u16 stat; |
581 | 564 | ||
582 | if (is_pbm_a) { | 565 | csr = psycho_read(pbm->pci_csr); |
583 | csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL; | ||
584 | } else { | ||
585 | csr_reg = pbm->controller_regs + PSYCHO_PCIB_CTRL; | ||
586 | } | ||
587 | csr = psycho_read(csr_reg); | ||
588 | csr_error_bits = | 566 | csr_error_bits = |
589 | csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR); | 567 | csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR); |
590 | if (csr_error_bits) { | 568 | if (csr_error_bits) { |
591 | /* Clear the errors. */ | 569 | /* Clear the errors. */ |
592 | psycho_write(csr_reg, csr); | 570 | psycho_write(pbm->pci_csr, csr); |
593 | 571 | ||
594 | /* Log 'em. */ | 572 | /* Log 'em. */ |
595 | if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR) | 573 | if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR) |
@@ -616,19 +594,12 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm | |||
616 | static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | 594 | static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) |
617 | { | 595 | { |
618 | struct pci_pbm_info *pbm = dev_id; | 596 | struct pci_pbm_info *pbm = dev_id; |
619 | struct pci_controller_info *p = pbm->parent; | ||
620 | unsigned long afsr_reg, afar_reg; | 597 | unsigned long afsr_reg, afar_reg; |
621 | unsigned long afsr, afar, error_bits; | 598 | unsigned long afsr, afar, error_bits; |
622 | int is_pbm_a, reported; | 599 | int reported; |
623 | 600 | ||
624 | is_pbm_a = (pbm == &pbm->parent->pbm_A); | 601 | afsr_reg = pbm->pci_afsr; |
625 | if (is_pbm_a) { | 602 | afar_reg = pbm->pci_afar; |
626 | afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_A; | ||
627 | afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_A; | ||
628 | } else { | ||
629 | afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_B; | ||
630 | afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_B; | ||
631 | } | ||
632 | 603 | ||
633 | /* Latch error status. */ | 604 | /* Latch error status. */ |
634 | afar = psycho_read(afar_reg); | 605 | afar = psycho_read(afar_reg); |
@@ -641,7 +612,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
641 | PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA | | 612 | PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA | |
642 | PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR); | 613 | PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR); |
643 | if (!error_bits) | 614 | if (!error_bits) |
644 | return psycho_pcierr_intr_other(pbm, is_pbm_a); | 615 | return psycho_pcierr_intr_other(pbm); |
645 | psycho_write(afsr_reg, error_bits); | 616 | psycho_write(afsr_reg, error_bits); |
646 | 617 | ||
647 | /* Log the error. */ | 618 | /* Log the error. */ |
@@ -923,10 +894,16 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, | |||
923 | pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A; | 894 | pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A; |
924 | pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A; | 895 | pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A; |
925 | pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_A; | 896 | pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_A; |
897 | pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_A; | ||
898 | pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_A; | ||
899 | pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_A; | ||
926 | } else { | 900 | } else { |
927 | pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_B; | 901 | pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_B; |
928 | pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B; | 902 | pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B; |
929 | pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B; | 903 | pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B; |
904 | pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_B; | ||
905 | pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_B; | ||
906 | pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_B; | ||
930 | } | 907 | } |
931 | /* PSYCHO's streaming buffer lacks ctx flushing. */ | 908 | /* PSYCHO's streaming buffer lacks ctx flushing. */ |
932 | pbm->stc.strbuf_ctxflush = 0; | 909 | pbm->stc.strbuf_ctxflush = 0; |
@@ -971,16 +948,10 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, | |||
971 | #define PSYCHO_MEMSPACE_B 0x180000000UL | 948 | #define PSYCHO_MEMSPACE_B 0x180000000UL |
972 | #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL | 949 | #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL |
973 | 950 | ||
974 | static void __init psycho_pbm_init(struct pci_controller_info *p, | 951 | static void __init psycho_pbm_init(struct pci_pbm_info *pbm, |
975 | struct of_device *op, int is_pbm_a) | 952 | struct of_device *op, int is_pbm_a) |
976 | { | 953 | { |
977 | struct device_node *dp = op->node; | 954 | struct device_node *dp = op->node; |
978 | struct pci_pbm_info *pbm; | ||
979 | |||
980 | if (is_pbm_a) | ||
981 | pbm = &p->pbm_A; | ||
982 | else | ||
983 | pbm = &p->pbm_B; | ||
984 | 955 | ||
985 | pbm->next = pci_pbm_root; | 956 | pbm->next = pci_pbm_root; |
986 | pci_pbm_root = pbm; | 957 | pci_pbm_root = pbm; |
@@ -996,7 +967,6 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, | |||
996 | pbm->chip_version = of_getintprop_default(dp, "version#", 0); | 967 | pbm->chip_version = of_getintprop_default(dp, "version#", 0); |
997 | pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0); | 968 | pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0); |
998 | 969 | ||
999 | pbm->parent = p; | ||
1000 | pbm->prom_node = dp; | 970 | pbm->prom_node = dp; |
1001 | pbm->name = dp->full_name; | 971 | pbm->name = dp->full_name; |
1002 | 972 | ||
@@ -1013,6 +983,17 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, | |||
1013 | psycho_scan_bus(pbm, &op->dev); | 983 | psycho_scan_bus(pbm, &op->dev); |
1014 | } | 984 | } |
1015 | 985 | ||
986 | static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid) | ||
987 | { | ||
988 | struct pci_pbm_info *pbm; | ||
989 | |||
990 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | ||
991 | if (pbm->portid == upa_portid) | ||
992 | return pbm; | ||
993 | } | ||
994 | return NULL; | ||
995 | } | ||
996 | |||
1016 | #define PSYCHO_CONFIGSPACE 0x001000000UL | 997 | #define PSYCHO_CONFIGSPACE 0x001000000UL |
1017 | 998 | ||
1018 | static int __devinit psycho_probe(struct of_device *op, | 999 | static int __devinit psycho_probe(struct of_device *op, |
@@ -1020,7 +1001,6 @@ static int __devinit psycho_probe(struct of_device *op, | |||
1020 | { | 1001 | { |
1021 | const struct linux_prom64_registers *pr_regs; | 1002 | const struct linux_prom64_registers *pr_regs; |
1022 | struct device_node *dp = op->node; | 1003 | struct device_node *dp = op->node; |
1023 | struct pci_controller_info *p; | ||
1024 | struct pci_pbm_info *pbm; | 1004 | struct pci_pbm_info *pbm; |
1025 | struct iommu *iommu; | 1005 | struct iommu *iommu; |
1026 | int is_pbm_a, err; | 1006 | int is_pbm_a, err; |
@@ -1028,33 +1008,26 @@ static int __devinit psycho_probe(struct of_device *op, | |||
1028 | 1008 | ||
1029 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); | 1009 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); |
1030 | 1010 | ||
1031 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | ||
1032 | struct pci_controller_info *p = pbm->parent; | ||
1033 | |||
1034 | if (p->pbm_A.portid == upa_portid) { | ||
1035 | is_pbm_a = (p->pbm_A.prom_node == NULL); | ||
1036 | psycho_pbm_init(p, op, is_pbm_a); | ||
1037 | return 0; | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | err = -ENOMEM; | 1011 | err = -ENOMEM; |
1042 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 1012 | pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); |
1043 | if (!p) { | 1013 | if (!pbm) { |
1044 | printk(KERN_ERR PFX "Cannot allocate controller info.\n"); | 1014 | printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); |
1045 | goto out_err; | 1015 | goto out_err; |
1046 | } | 1016 | } |
1047 | 1017 | ||
1048 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 1018 | pbm->sibling = psycho_find_sibling(upa_portid); |
1049 | if (!iommu) { | 1019 | if (pbm->sibling) { |
1050 | printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); | 1020 | iommu = pbm->sibling->iommu; |
1051 | goto out_free_controller; | 1021 | } else { |
1022 | iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); | ||
1023 | if (!iommu) { | ||
1024 | printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); | ||
1025 | goto out_free_controller; | ||
1026 | } | ||
1052 | } | 1027 | } |
1053 | 1028 | ||
1054 | p->pbm_A.iommu = p->pbm_B.iommu = iommu; | 1029 | pbm->iommu = iommu; |
1055 | 1030 | pbm->portid = upa_portid; | |
1056 | p->pbm_A.portid = upa_portid; | ||
1057 | p->pbm_B.portid = upa_portid; | ||
1058 | 1031 | ||
1059 | pr_regs = of_get_property(dp, "reg", NULL); | 1032 | pr_regs = of_get_property(dp, "reg", NULL); |
1060 | err = -ENODEV; | 1033 | err = -ENODEV; |
@@ -1063,29 +1036,43 @@ static int __devinit psycho_probe(struct of_device *op, | |||
1063 | goto out_free_iommu; | 1036 | goto out_free_iommu; |
1064 | } | 1037 | } |
1065 | 1038 | ||
1066 | p->pbm_A.controller_regs = pr_regs[2].phys_addr; | 1039 | is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); |
1067 | p->pbm_B.controller_regs = pr_regs[2].phys_addr; | 1040 | |
1041 | pbm->controller_regs = pr_regs[2].phys_addr; | ||
1042 | pbm->config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); | ||
1068 | 1043 | ||
1069 | p->pbm_A.config_space = p->pbm_B.config_space = | 1044 | if (is_pbm_a) { |
1070 | (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); | 1045 | pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_A; |
1046 | pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_A; | ||
1047 | pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIA_CTRL; | ||
1048 | } else { | ||
1049 | pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_B; | ||
1050 | pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_B; | ||
1051 | pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIB_CTRL; | ||
1052 | } | ||
1071 | 1053 | ||
1072 | psycho_controller_hwinit(&p->pbm_A); | 1054 | psycho_controller_hwinit(pbm); |
1055 | if (!pbm->sibling) { | ||
1056 | err = psycho_iommu_init(pbm); | ||
1057 | if (err) | ||
1058 | goto out_free_iommu; | ||
1059 | } | ||
1073 | 1060 | ||
1074 | err = psycho_iommu_init(&p->pbm_A); | 1061 | psycho_pbm_init(pbm, op, is_pbm_a); |
1075 | if (err) | ||
1076 | goto out_free_iommu; | ||
1077 | 1062 | ||
1078 | is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); | 1063 | if (pbm->sibling) |
1064 | pbm->sibling->sibling = pbm; | ||
1079 | 1065 | ||
1080 | psycho_pbm_init(p, op, is_pbm_a); | 1066 | dev_set_drvdata(&op->dev, pbm); |
1081 | 1067 | ||
1082 | return 0; | 1068 | return 0; |
1083 | 1069 | ||
1084 | out_free_iommu: | 1070 | out_free_iommu: |
1085 | kfree(p->pbm_A.iommu); | 1071 | if (!pbm->sibling) |
1072 | kfree(pbm->iommu); | ||
1086 | 1073 | ||
1087 | out_free_controller: | 1074 | out_free_controller: |
1088 | kfree(p); | 1075 | kfree(pbm); |
1089 | 1076 | ||
1090 | out_err: | 1077 | out_err: |
1091 | return err; | 1078 | return err; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 707d6d6130f7..8f779b58d65a 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -734,8 +734,8 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm, | |||
734 | return 0; | 734 | return 0; |
735 | } | 735 | } |
736 | 736 | ||
737 | static void __init sabre_pbm_init(struct pci_controller_info *p, | 737 | static void __init sabre_pbm_init(struct pci_pbm_info *pbm, |
738 | struct pci_pbm_info *pbm, struct of_device *op) | 738 | struct of_device *op) |
739 | { | 739 | { |
740 | struct device_node *dp = op->node; | 740 | struct device_node *dp = op->node; |
741 | 741 | ||
@@ -750,7 +750,6 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, | |||
750 | pbm->index = pci_num_pbms++; | 750 | pbm->index = pci_num_pbms++; |
751 | 751 | ||
752 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; | 752 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; |
753 | pbm->parent = p; | ||
754 | pbm->prom_node = dp; | 753 | pbm->prom_node = dp; |
755 | pci_get_pbm_props(pbm); | 754 | pci_get_pbm_props(pbm); |
756 | 755 | ||
@@ -764,7 +763,6 @@ static int __devinit sabre_probe(struct of_device *op, | |||
764 | { | 763 | { |
765 | const struct linux_prom64_registers *pr_regs; | 764 | const struct linux_prom64_registers *pr_regs; |
766 | struct device_node *dp = op->node; | 765 | struct device_node *dp = op->node; |
767 | struct pci_controller_info *p; | ||
768 | struct pci_pbm_info *pbm; | 766 | struct pci_pbm_info *pbm; |
769 | u32 upa_portid, dma_mask; | 767 | u32 upa_portid, dma_mask; |
770 | struct iommu *iommu; | 768 | struct iommu *iommu; |
@@ -786,26 +784,22 @@ static int __devinit sabre_probe(struct of_device *op, | |||
786 | } | 784 | } |
787 | 785 | ||
788 | err = -ENOMEM; | 786 | err = -ENOMEM; |
789 | p = kzalloc(sizeof(*p), GFP_ATOMIC); | 787 | pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); |
790 | if (!p) { | 788 | if (!pbm) { |
791 | printk(KERN_ERR PFX "Cannot allocate controller info.\n"); | 789 | printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); |
792 | goto out_err; | 790 | goto out_err; |
793 | } | 791 | } |
794 | 792 | ||
795 | iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); | 793 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); |
796 | if (!iommu) { | 794 | if (!iommu) { |
797 | printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); | 795 | printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); |
798 | goto out_free_controller; | 796 | goto out_free_controller; |
799 | } | 797 | } |
800 | 798 | ||
801 | pbm = &p->pbm_A; | ||
802 | pbm->iommu = iommu; | 799 | pbm->iommu = iommu; |
803 | 800 | ||
804 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); | 801 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); |
805 | 802 | ||
806 | pbm->next = pci_pbm_root; | ||
807 | pci_pbm_root = pbm; | ||
808 | |||
809 | pbm->portid = upa_portid; | 803 | pbm->portid = upa_portid; |
810 | 804 | ||
811 | /* | 805 | /* |
@@ -840,8 +834,7 @@ static int __devinit sabre_probe(struct of_device *op, | |||
840 | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); | 834 | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); |
841 | 835 | ||
842 | /* Now map in PCI config space for entire SABRE. */ | 836 | /* Now map in PCI config space for entire SABRE. */ |
843 | pbm->config_space = | 837 | pbm->config_space = pbm->controller_regs + SABRE_CONFIGSPACE; |
844 | (pbm->controller_regs + SABRE_CONFIGSPACE); | ||
845 | 838 | ||
846 | vdma = of_get_property(dp, "virtual-dma", NULL); | 839 | vdma = of_get_property(dp, "virtual-dma", NULL); |
847 | if (!vdma) { | 840 | if (!vdma) { |
@@ -876,14 +869,20 @@ static int __devinit sabre_probe(struct of_device *op, | |||
876 | /* | 869 | /* |
877 | * Look for APB underneath. | 870 | * Look for APB underneath. |
878 | */ | 871 | */ |
879 | sabre_pbm_init(p, pbm, op); | 872 | sabre_pbm_init(pbm, op); |
873 | |||
874 | pbm->next = pci_pbm_root; | ||
875 | pci_pbm_root = pbm; | ||
876 | |||
877 | dev_set_drvdata(&op->dev, pbm); | ||
878 | |||
880 | return 0; | 879 | return 0; |
881 | 880 | ||
882 | out_free_iommu: | 881 | out_free_iommu: |
883 | kfree(p->pbm_A.iommu); | 882 | kfree(pbm->iommu); |
884 | 883 | ||
885 | out_free_controller: | 884 | out_free_controller: |
886 | kfree(p); | 885 | kfree(pbm); |
887 | 886 | ||
888 | out_err: | 887 | out_err: |
889 | return err; | 888 | return err; |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e1c565744d3f..67e3640bc69a 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -358,11 +358,12 @@ static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm, | |||
358 | spin_unlock_irqrestore(&iommu->lock, flags); | 358 | spin_unlock_irqrestore(&iommu->lock, flags); |
359 | } | 359 | } |
360 | 360 | ||
361 | static void schizo_check_iommu_error(struct pci_controller_info *p, | 361 | static void schizo_check_iommu_error(struct pci_pbm_info *pbm, |
362 | enum schizo_error_type type) | 362 | enum schizo_error_type type) |
363 | { | 363 | { |
364 | schizo_check_iommu_error_pbm(&p->pbm_A, type); | 364 | schizo_check_iommu_error_pbm(pbm, type); |
365 | schizo_check_iommu_error_pbm(&p->pbm_B, type); | 365 | if (pbm->sibling) |
366 | schizo_check_iommu_error_pbm(pbm->sibling, type); | ||
366 | } | 367 | } |
367 | 368 | ||
368 | /* Uncorrectable ECC error status gathering. */ | 369 | /* Uncorrectable ECC error status gathering. */ |
@@ -387,7 +388,6 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, | |||
387 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | 388 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) |
388 | { | 389 | { |
389 | struct pci_pbm_info *pbm = dev_id; | 390 | struct pci_pbm_info *pbm = dev_id; |
390 | struct pci_controller_info *p = pbm->parent; | ||
391 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; | 391 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; |
392 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; | 392 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; |
393 | unsigned long afsr, afar, error_bits; | 393 | unsigned long afsr, afar, error_bits; |
@@ -450,7 +450,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | |||
450 | printk("]\n"); | 450 | printk("]\n"); |
451 | 451 | ||
452 | /* Interrogate IOMMU for error status. */ | 452 | /* Interrogate IOMMU for error status. */ |
453 | schizo_check_iommu_error(p, UE_ERR); | 453 | schizo_check_iommu_error(pbm, UE_ERR); |
454 | 454 | ||
455 | return IRQ_HANDLED; | 455 | return IRQ_HANDLED; |
456 | } | 456 | } |
@@ -651,7 +651,6 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) | |||
651 | static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | 651 | static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) |
652 | { | 652 | { |
653 | struct pci_pbm_info *pbm = dev_id; | 653 | struct pci_pbm_info *pbm = dev_id; |
654 | struct pci_controller_info *p = pbm->parent; | ||
655 | unsigned long afsr_reg, afar_reg, base; | 654 | unsigned long afsr_reg, afar_reg, base; |
656 | unsigned long afsr, afar, error_bits; | 655 | unsigned long afsr, afar, error_bits; |
657 | int reported; | 656 | int reported; |
@@ -745,7 +744,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
745 | * a bug in the IOMMU support code or a PCI device driver. | 744 | * a bug in the IOMMU support code or a PCI device driver. |
746 | */ | 745 | */ |
747 | if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { | 746 | if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { |
748 | schizo_check_iommu_error(p, PCI_ERR); | 747 | schizo_check_iommu_error(pbm, PCI_ERR); |
749 | pci_scan_for_target_abort(pbm, pbm->pci_bus); | 748 | pci_scan_for_target_abort(pbm, pbm->pci_bus); |
750 | } | 749 | } |
751 | if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) | 750 | if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) |
@@ -806,7 +805,6 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
806 | static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | 805 | static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) |
807 | { | 806 | { |
808 | struct pci_pbm_info *pbm = dev_id; | 807 | struct pci_pbm_info *pbm = dev_id; |
809 | struct pci_controller_info *p = pbm->parent; | ||
810 | u64 errlog; | 808 | u64 errlog; |
811 | 809 | ||
812 | errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); | 810 | errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); |
@@ -822,7 +820,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | |||
822 | 820 | ||
823 | printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", | 821 | printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", |
824 | pbm->name); | 822 | pbm->name); |
825 | schizo_check_iommu_error(p, SAFARI_ERR); | 823 | schizo_check_iommu_error(pbm, SAFARI_ERR); |
826 | 824 | ||
827 | return IRQ_HANDLED; | 825 | return IRQ_HANDLED; |
828 | } | 826 | } |
@@ -1329,13 +1327,12 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) | |||
1329 | } | 1327 | } |
1330 | } | 1328 | } |
1331 | 1329 | ||
1332 | static int __devinit schizo_pbm_init(struct pci_controller_info *p, | 1330 | static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, |
1333 | struct of_device *op, u32 portid, | 1331 | struct of_device *op, u32 portid, |
1334 | int chip_type) | 1332 | int chip_type) |
1335 | { | 1333 | { |
1336 | const struct linux_prom64_registers *regs; | 1334 | const struct linux_prom64_registers *regs; |
1337 | struct device_node *dp = op->node; | 1335 | struct device_node *dp = op->node; |
1338 | struct pci_pbm_info *pbm; | ||
1339 | const char *chipset_name; | 1336 | const char *chipset_name; |
1340 | int is_pbm_a, err; | 1337 | int is_pbm_a, err; |
1341 | 1338 | ||
@@ -1368,10 +1365,6 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p, | |||
1368 | regs = of_get_property(dp, "reg", NULL); | 1365 | regs = of_get_property(dp, "reg", NULL); |
1369 | 1366 | ||
1370 | is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); | 1367 | is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); |
1371 | if (is_pbm_a) | ||
1372 | pbm = &p->pbm_A; | ||
1373 | else | ||
1374 | pbm = &p->pbm_B; | ||
1375 | 1368 | ||
1376 | pbm->next = pci_pbm_root; | 1369 | pbm->next = pci_pbm_root; |
1377 | pci_pbm_root = pbm; | 1370 | pci_pbm_root = pbm; |
@@ -1384,7 +1377,6 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p, | |||
1384 | pbm->index = pci_num_pbms++; | 1377 | pbm->index = pci_num_pbms++; |
1385 | 1378 | ||
1386 | pbm->portid = portid; | 1379 | pbm->portid = portid; |
1387 | pbm->parent = p; | ||
1388 | pbm->prom_node = dp; | 1380 | pbm->prom_node = dp; |
1389 | 1381 | ||
1390 | pbm->chip_type = chip_type; | 1382 | pbm->chip_type = chip_type; |
@@ -1430,10 +1422,21 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1430 | return (x == y); | 1422 | return (x == y); |
1431 | } | 1423 | } |
1432 | 1424 | ||
1425 | static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, | ||
1426 | int chip_type) | ||
1427 | { | ||
1428 | struct pci_pbm_info *pbm; | ||
1429 | |||
1430 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | ||
1431 | if (portid_compare(pbm->portid, portid, chip_type)) | ||
1432 | return pbm; | ||
1433 | } | ||
1434 | return NULL; | ||
1435 | } | ||
1436 | |||
1433 | static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) | 1437 | static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) |
1434 | { | 1438 | { |
1435 | struct device_node *dp = op->node; | 1439 | struct device_node *dp = op->node; |
1436 | struct pci_controller_info *p; | ||
1437 | struct pci_pbm_info *pbm; | 1440 | struct pci_pbm_info *pbm; |
1438 | struct iommu *iommu; | 1441 | struct iommu *iommu; |
1439 | u32 portid; | 1442 | u32 portid; |
@@ -1442,50 +1445,37 @@ static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type | |||
1442 | portid = of_getintprop_default(dp, "portid", 0xff); | 1445 | portid = of_getintprop_default(dp, "portid", 0xff); |
1443 | 1446 | ||
1444 | err = -ENOMEM; | 1447 | err = -ENOMEM; |
1445 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | 1448 | pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); |
1446 | if (portid_compare(pbm->portid, portid, chip_type)) { | 1449 | if (!pbm) { |
1447 | if (schizo_pbm_init(pbm->parent, op, | 1450 | printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); |
1448 | portid, chip_type)) | ||
1449 | goto out_err; | ||
1450 | return 0; | ||
1451 | } | ||
1452 | } | ||
1453 | |||
1454 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | ||
1455 | if (!p) { | ||
1456 | printk(KERN_ERR PFX "Cannot allocate controller info.\n"); | ||
1457 | goto out_err; | 1451 | goto out_err; |
1458 | } | 1452 | } |
1459 | 1453 | ||
1460 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 1454 | pbm->sibling = schizo_find_sibling(portid, chip_type); |
1455 | |||
1456 | iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); | ||
1461 | if (!iommu) { | 1457 | if (!iommu) { |
1462 | printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); | 1458 | printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); |
1463 | goto out_free_controller; | 1459 | goto out_free_pbm; |
1464 | } | 1460 | } |
1465 | 1461 | ||
1466 | p->pbm_A.iommu = iommu; | 1462 | pbm->iommu = iommu; |
1467 | 1463 | ||
1468 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 1464 | if (schizo_pbm_init(pbm, op, portid, chip_type)) |
1469 | if (!iommu) { | 1465 | goto out_free_iommu; |
1470 | printk(KERN_ERR PFX "Cannot allocate PBM B iommu.\n"); | ||
1471 | goto out_free_iommu_A; | ||
1472 | } | ||
1473 | 1466 | ||
1474 | p->pbm_B.iommu = iommu; | 1467 | if (pbm->sibling) |
1468 | pbm->sibling->sibling = pbm; | ||
1475 | 1469 | ||
1476 | if (schizo_pbm_init(p, op, portid, chip_type)) | 1470 | dev_set_drvdata(&op->dev, pbm); |
1477 | goto out_free_iommu_B; | ||
1478 | 1471 | ||
1479 | return 0; | 1472 | return 0; |
1480 | 1473 | ||
1481 | out_free_iommu_B: | 1474 | out_free_iommu: |
1482 | kfree(p->pbm_B.iommu); | 1475 | kfree(pbm->iommu); |
1483 | |||
1484 | out_free_iommu_A: | ||
1485 | kfree(p->pbm_A.iommu); | ||
1486 | 1476 | ||
1487 | out_free_controller: | 1477 | out_free_pbm: |
1488 | kfree(p); | 1478 | kfree(pbm); |
1489 | 1479 | ||
1490 | out_err: | 1480 | out_err: |
1491 | return err; | 1481 | return err; |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 6bed2f6bf7cd..233b22b8b576 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -42,6 +42,7 @@ struct iommu_batch { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | static DEFINE_PER_CPU(struct iommu_batch, iommu_batch); | 44 | static DEFINE_PER_CPU(struct iommu_batch, iommu_batch); |
45 | static int iommu_batch_initialized; | ||
45 | 46 | ||
46 | /* Interrupts must be disabled. */ | 47 | /* Interrupts must be disabled. */ |
47 | static inline void iommu_batch_start(struct device *dev, unsigned long prot, unsigned long entry) | 48 | static inline void iommu_batch_start(struct device *dev, unsigned long prot, unsigned long entry) |
@@ -887,21 +888,12 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | |||
887 | } | 888 | } |
888 | #endif /* !(CONFIG_PCI_MSI) */ | 889 | #endif /* !(CONFIG_PCI_MSI) */ |
889 | 890 | ||
890 | static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, | 891 | static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm, |
891 | struct of_device *op, u32 devhandle) | 892 | struct of_device *op, u32 devhandle) |
892 | { | 893 | { |
893 | struct device_node *dp = op->node; | 894 | struct device_node *dp = op->node; |
894 | struct pci_pbm_info *pbm; | ||
895 | int err; | 895 | int err; |
896 | 896 | ||
897 | if (devhandle & 0x40) | ||
898 | pbm = &p->pbm_B; | ||
899 | else | ||
900 | pbm = &p->pbm_A; | ||
901 | |||
902 | pbm->next = pci_pbm_root; | ||
903 | pci_pbm_root = pbm; | ||
904 | |||
905 | pbm->numa_node = of_node_to_nid(dp); | 897 | pbm->numa_node = of_node_to_nid(dp); |
906 | 898 | ||
907 | pbm->pci_ops = &sun4v_pci_ops; | 899 | pbm->pci_ops = &sun4v_pci_ops; |
@@ -909,7 +901,6 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, | |||
909 | 901 | ||
910 | pbm->index = pci_num_pbms++; | 902 | pbm->index = pci_num_pbms++; |
911 | 903 | ||
912 | pbm->parent = p; | ||
913 | pbm->prom_node = dp; | 904 | pbm->prom_node = dp; |
914 | 905 | ||
915 | pbm->devhandle = devhandle; | 906 | pbm->devhandle = devhandle; |
@@ -931,6 +922,9 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, | |||
931 | 922 | ||
932 | pci_sun4v_scan_bus(pbm, &op->dev); | 923 | pci_sun4v_scan_bus(pbm, &op->dev); |
933 | 924 | ||
925 | pbm->next = pci_pbm_root; | ||
926 | pci_pbm_root = pbm; | ||
927 | |||
934 | return 0; | 928 | return 0; |
935 | } | 929 | } |
936 | 930 | ||
@@ -939,7 +933,6 @@ static int __devinit pci_sun4v_probe(struct of_device *op, | |||
939 | { | 933 | { |
940 | const struct linux_prom64_registers *regs; | 934 | const struct linux_prom64_registers *regs; |
941 | static int hvapi_negotiated = 0; | 935 | static int hvapi_negotiated = 0; |
942 | struct pci_controller_info *p; | ||
943 | struct pci_pbm_info *pbm; | 936 | struct pci_pbm_info *pbm; |
944 | struct device_node *dp; | 937 | struct device_node *dp; |
945 | struct iommu *iommu; | 938 | struct iommu *iommu; |
@@ -972,51 +965,46 @@ static int __devinit pci_sun4v_probe(struct of_device *op, | |||
972 | } | 965 | } |
973 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; | 966 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; |
974 | 967 | ||
975 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | ||
976 | if (pbm->devhandle == (devhandle ^ 0x40)) { | ||
977 | return pci_sun4v_pbm_init(pbm->parent, op, devhandle); | ||
978 | } | ||
979 | } | ||
980 | |||
981 | err = -ENOMEM; | 968 | err = -ENOMEM; |
982 | for_each_possible_cpu(i) { | 969 | if (!iommu_batch_initialized) { |
983 | unsigned long page = get_zeroed_page(GFP_ATOMIC); | 970 | for_each_possible_cpu(i) { |
971 | unsigned long page = get_zeroed_page(GFP_KERNEL); | ||
984 | 972 | ||
985 | if (!page) | 973 | if (!page) |
986 | goto out_err; | 974 | goto out_err; |
987 | 975 | ||
988 | per_cpu(iommu_batch, i).pglist = (u64 *) page; | 976 | per_cpu(iommu_batch, i).pglist = (u64 *) page; |
977 | } | ||
978 | iommu_batch_initialized = 1; | ||
989 | } | 979 | } |
990 | 980 | ||
991 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 981 | pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); |
992 | if (!p) { | 982 | if (!pbm) { |
993 | printk(KERN_ERR PFX "Could not allocate pci_controller_info\n"); | 983 | printk(KERN_ERR PFX "Could not allocate pci_pbm_info\n"); |
994 | goto out_err; | 984 | goto out_err; |
995 | } | 985 | } |
996 | 986 | ||
997 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 987 | iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); |
998 | if (!iommu) { | 988 | if (!iommu) { |
999 | printk(KERN_ERR PFX "Could not allocate pbm A iommu\n"); | 989 | printk(KERN_ERR PFX "Could not allocate pbm iommu\n"); |
1000 | goto out_free_controller; | 990 | goto out_free_controller; |
1001 | } | 991 | } |
1002 | 992 | ||
1003 | p->pbm_A.iommu = iommu; | 993 | pbm->iommu = iommu; |
1004 | 994 | ||
1005 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 995 | err = pci_sun4v_pbm_init(pbm, op, devhandle); |
1006 | if (!iommu) { | 996 | if (err) |
1007 | printk(KERN_ERR PFX "Could not allocate pbm B iommu\n"); | 997 | goto out_free_iommu; |
1008 | goto out_free_iommu_A; | ||
1009 | } | ||
1010 | 998 | ||
1011 | p->pbm_B.iommu = iommu; | 999 | dev_set_drvdata(&op->dev, pbm); |
1012 | 1000 | ||
1013 | return pci_sun4v_pbm_init(p, op, devhandle); | 1001 | return 0; |
1014 | 1002 | ||
1015 | out_free_iommu_A: | 1003 | out_free_iommu: |
1016 | kfree(p->pbm_A.iommu); | 1004 | kfree(pbm->iommu); |
1017 | 1005 | ||
1018 | out_free_controller: | 1006 | out_free_controller: |
1019 | kfree(p); | 1007 | kfree(pbm); |
1020 | 1008 | ||
1021 | out_err: | 1009 | out_err: |
1022 | return err; | 1010 | return err; |