diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-08 02:06:27 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-08 19:41:24 -0400 |
commit | 34768bc8329194b14e42ee408a84edfa40059046 (patch) | |
tree | 3fff53138966f3a58e796a71c19a3b75de86fbf7 | |
parent | 5a4a3e592d0d66653297049373caa7ac5b4febe0 (diff) |
[SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's
The idea is to move more and more things into the pbm,
with the eventual goal of eliminating the pci_controller_info
entirely as there really isn't any need for it.
This stage of the transformations requires some reworking of
the PCI error interrupt handling.
It might be tricky to get rid of the pci_controller_info parenting for
a few reasons:
1) When we get an uncorrectable or correctable error we want
to interrogate the IOMMU and streaming cache of both
PBMs for error status. These errors come from the UPA
front-end which is shared between the two PBM PCI bus
segments.
Historically speaking this is why I choose the datastructure
hierarchy of pci_controller_info-->pci_pbm_info
2) The probing does a portid/devhandle match to look for the
'other' pbm, but this is entirely an artifact and can be
eliminated trivially.
What we could do to solve #1 is to have a "buddy" pointer from one pbm
to another.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/pci.c | 12 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_fire.c | 39 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_impl.h | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 107 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 31 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 256 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 47 | ||||
-rw-r--r-- | include/asm-sparc64/pbm.h | 8 |
8 files changed, 187 insertions, 315 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 966861b212be..c17723fb1c31 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -48,7 +48,7 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, | |||
48 | #else | 48 | #else |
49 | 49 | ||
50 | /* List of all PCI controllers found in the system. */ | 50 | /* List of all PCI controllers found in the system. */ |
51 | struct pci_controller_info *pci_controller_root = NULL; | 51 | struct pci_pbm_info *pci_pbm_root = NULL; |
52 | 52 | ||
53 | /* Each PCI controller found gets a unique index. */ | 53 | /* Each PCI controller found gets a unique index. */ |
54 | int pci_num_controllers = 0; | 54 | int pci_num_controllers = 0; |
@@ -291,7 +291,7 @@ extern const struct pci_iommu_ops pci_sun4u_iommu_ops, | |||
291 | 291 | ||
292 | /* Find each controller in the system, attach and initialize | 292 | /* Find each controller in the system, attach and initialize |
293 | * software state structure for each and link into the | 293 | * software state structure for each and link into the |
294 | * pci_controller_root. Setup the controller enough such | 294 | * pci_pbm_root. Setup the controller enough such |
295 | * that bus scanning can be done. | 295 | * that bus scanning can be done. |
296 | */ | 296 | */ |
297 | static void __init pci_controller_probe(void) | 297 | static void __init pci_controller_probe(void) |
@@ -776,10 +776,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | |||
776 | 776 | ||
777 | static void __init pci_scan_each_controller_bus(void) | 777 | static void __init pci_scan_each_controller_bus(void) |
778 | { | 778 | { |
779 | struct pci_controller_info *p; | 779 | struct pci_pbm_info *pbm; |
780 | 780 | ||
781 | for (p = pci_controller_root; p; p = p->next) | 781 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) |
782 | p->scan_bus(p); | 782 | pbm->scan_bus(pbm); |
783 | } | 783 | } |
784 | 784 | ||
785 | extern void power_init(void); | 785 | extern void power_init(void); |
@@ -787,7 +787,7 @@ extern void power_init(void); | |||
787 | static int __init pcibios_init(void) | 787 | static int __init pcibios_init(void) |
788 | { | 788 | { |
789 | pci_controller_probe(); | 789 | pci_controller_probe(); |
790 | if (pci_controller_root == NULL) | 790 | if (pci_pbm_root == NULL) |
791 | return 0; | 791 | return 0; |
792 | 792 | ||
793 | pci_scan_each_controller_bus(); | 793 | pci_scan_each_controller_bus(); |
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 79ee5be948eb..f55c08ae0aa0 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c | |||
@@ -160,21 +160,9 @@ static struct pci_ops pci_fire_ops = { | |||
160 | .write = fire_write_pci_cfg, | 160 | .write = fire_write_pci_cfg, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static void pbm_scan_bus(struct pci_controller_info *p, | 163 | static void pci_fire_scan_bus(struct pci_pbm_info *pbm) |
164 | struct pci_pbm_info *pbm) | ||
165 | { | 164 | { |
166 | pbm->pci_bus = pci_scan_one_pbm(pbm); | 165 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
167 | } | ||
168 | |||
169 | static void pci_fire_scan_bus(struct pci_controller_info *p) | ||
170 | { | ||
171 | struct device_node *dp; | ||
172 | |||
173 | if ((dp = p->pbm_A.prom_node) != NULL) | ||
174 | pbm_scan_bus(p, &p->pbm_A); | ||
175 | |||
176 | if ((dp = p->pbm_B.prom_node) != NULL) | ||
177 | pbm_scan_bus(p, &p->pbm_B); | ||
178 | 166 | ||
179 | /* XXX register error interrupt handlers XXX */ | 167 | /* XXX register error interrupt handlers XXX */ |
180 | } | 168 | } |
@@ -313,7 +301,7 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) | |||
313 | } | 301 | } |
314 | 302 | ||
315 | static void pci_fire_pbm_init(struct pci_controller_info *p, | 303 | static void pci_fire_pbm_init(struct pci_controller_info *p, |
316 | struct device_node *dp, u32 portid) | 304 | struct device_node *dp, u32 portid) |
317 | { | 305 | { |
318 | const struct linux_prom64_registers *regs; | 306 | const struct linux_prom64_registers *regs; |
319 | struct pci_pbm_info *pbm; | 307 | struct pci_pbm_info *pbm; |
@@ -323,6 +311,11 @@ static void pci_fire_pbm_init(struct pci_controller_info *p, | |||
323 | else | 311 | else |
324 | pbm = &p->pbm_B; | 312 | pbm = &p->pbm_B; |
325 | 313 | ||
314 | pbm->next = pci_pbm_root; | ||
315 | pci_pbm_root = pbm; | ||
316 | |||
317 | pbm->scan_bus = pci_fire_scan_bus; | ||
318 | |||
326 | pbm->portid = portid; | 319 | pbm->portid = portid; |
327 | pbm->parent = p; | 320 | pbm->parent = p; |
328 | pbm->prom_node = dp; | 321 | pbm->prom_node = dp; |
@@ -354,19 +347,11 @@ void fire_pci_init(struct device_node *dp, const char *model_name) | |||
354 | struct pci_controller_info *p; | 347 | struct pci_controller_info *p; |
355 | u32 portid = of_getintprop_default(dp, "portid", 0xff); | 348 | u32 portid = of_getintprop_default(dp, "portid", 0xff); |
356 | struct iommu *iommu; | 349 | struct iommu *iommu; |
350 | struct pci_pbm_info *pbm; | ||
357 | 351 | ||
358 | for (p = pci_controller_root; p; p = p->next) { | 352 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
359 | struct pci_pbm_info *pbm; | ||
360 | |||
361 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
362 | continue; | ||
363 | |||
364 | pbm = (p->pbm_A.prom_node ? | ||
365 | &p->pbm_A : | ||
366 | &p->pbm_B); | ||
367 | |||
368 | if (portid_compare(pbm->portid, portid)) { | 353 | if (portid_compare(pbm->portid, portid)) { |
369 | pci_fire_pbm_init(p, dp, portid); | 354 | pci_fire_pbm_init(pbm->parent, dp, portid); |
370 | return; | 355 | return; |
371 | } | 356 | } |
372 | } | 357 | } |
@@ -387,12 +372,8 @@ void fire_pci_init(struct device_node *dp, const char *model_name) | |||
387 | 372 | ||
388 | p->pbm_B.iommu = iommu; | 373 | p->pbm_B.iommu = iommu; |
389 | 374 | ||
390 | p->next = pci_controller_root; | ||
391 | pci_controller_root = p; | ||
392 | |||
393 | p->index = pci_num_controllers++; | 375 | p->index = pci_num_controllers++; |
394 | 376 | ||
395 | p->scan_bus = pci_fire_scan_bus; | ||
396 | /* XXX MSI support XXX */ | 377 | /* XXX MSI support XXX */ |
397 | p->pci_ops = &pci_fire_ops; | 378 | p->pci_ops = &pci_fire_ops; |
398 | 379 | ||
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 41c3f5137306..3dd6d02b2d81 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <asm/io.h> | 11 | #include <asm/io.h> |
12 | #include <asm/prom.h> | 12 | #include <asm/prom.h> |
13 | 13 | ||
14 | extern struct pci_controller_info *pci_controller_root; | 14 | extern struct pci_pbm_info *pci_pbm_root; |
15 | extern unsigned long pci_memspace_mask; | 15 | extern unsigned long pci_memspace_mask; |
16 | 16 | ||
17 | extern int pci_num_controllers; | 17 | extern int pci_num_controllers; |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 0f35135a40c5..4801eb441236 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -265,12 +265,12 @@ static unsigned long stc_error_buf[128]; | |||
265 | static unsigned long stc_tag_buf[16]; | 265 | static unsigned long stc_tag_buf[16]; |
266 | static unsigned long stc_line_buf[16]; | 266 | static unsigned long stc_line_buf[16]; |
267 | 267 | ||
268 | static void __psycho_check_one_stc(struct pci_controller_info *p, | 268 | static void __psycho_check_one_stc(struct pci_pbm_info *pbm, |
269 | struct pci_pbm_info *pbm, | ||
270 | int is_pbm_a) | 269 | int is_pbm_a) |
271 | { | 270 | { |
271 | struct pci_controller_info *p = pbm->parent; | ||
272 | struct strbuf *strbuf = &pbm->stc; | 272 | struct strbuf *strbuf = &pbm->stc; |
273 | unsigned long regbase = p->pbm_A.controller_regs; | 273 | unsigned long regbase = pbm->controller_regs; |
274 | unsigned long err_base, tag_base, line_base; | 274 | unsigned long err_base, tag_base, line_base; |
275 | u64 control; | 275 | u64 control; |
276 | int i; | 276 | int i; |
@@ -362,20 +362,13 @@ static void __psycho_check_one_stc(struct pci_controller_info *p, | |||
362 | spin_unlock(&stc_buf_lock); | 362 | spin_unlock(&stc_buf_lock); |
363 | } | 363 | } |
364 | 364 | ||
365 | static void __psycho_check_stc_error(struct pci_controller_info *p, | 365 | static void __psycho_check_stc_error(struct pci_pbm_info *pbm, |
366 | unsigned long afsr, | 366 | unsigned long afsr, |
367 | unsigned long afar, | 367 | unsigned long afar, |
368 | enum psycho_error_type type) | 368 | enum psycho_error_type type) |
369 | { | 369 | { |
370 | struct pci_pbm_info *pbm; | 370 | __psycho_check_one_stc(pbm, |
371 | 371 | (pbm == &pbm->parent->pbm_A)); | |
372 | pbm = &p->pbm_A; | ||
373 | if (pbm->stc.strbuf_enabled) | ||
374 | __psycho_check_one_stc(p, pbm, 1); | ||
375 | |||
376 | pbm = &p->pbm_B; | ||
377 | if (pbm->stc.strbuf_enabled) | ||
378 | __psycho_check_one_stc(p, pbm, 0); | ||
379 | } | 372 | } |
380 | 373 | ||
381 | /* When an Uncorrectable Error or a PCI Error happens, we | 374 | /* When an Uncorrectable Error or a PCI Error happens, we |
@@ -413,12 +406,13 @@ static void __psycho_check_stc_error(struct pci_controller_info *p, | |||
413 | #define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL) | 406 | #define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL) |
414 | #define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL) | 407 | #define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL) |
415 | #define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL | 408 | #define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL |
416 | static void psycho_check_iommu_error(struct pci_controller_info *p, | 409 | static void psycho_check_iommu_error(struct pci_pbm_info *pbm, |
417 | unsigned long afsr, | 410 | unsigned long afsr, |
418 | unsigned long afar, | 411 | unsigned long afar, |
419 | enum psycho_error_type type) | 412 | enum psycho_error_type type) |
420 | { | 413 | { |
421 | struct iommu *iommu = p->pbm_A.iommu; | 414 | struct pci_controller_info *p = pbm->parent; |
415 | struct iommu *iommu = pbm->iommu; | ||
422 | unsigned long iommu_tag[16]; | 416 | unsigned long iommu_tag[16]; |
423 | unsigned long iommu_data[16]; | 417 | unsigned long iommu_data[16]; |
424 | unsigned long flags; | 418 | unsigned long flags; |
@@ -465,7 +459,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
465 | psycho_write(iommu->iommu_control, | 459 | psycho_write(iommu->iommu_control, |
466 | control | PSYCHO_IOMMU_CTRL_DENAB); | 460 | control | PSYCHO_IOMMU_CTRL_DENAB); |
467 | for (i = 0; i < 16; i++) { | 461 | for (i = 0; i < 16; i++) { |
468 | unsigned long base = p->pbm_A.controller_regs; | 462 | unsigned long base = pbm->controller_regs; |
469 | 463 | ||
470 | iommu_tag[i] = | 464 | iommu_tag[i] = |
471 | psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); | 465 | psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); |
@@ -516,7 +510,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
516 | (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); | 510 | (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); |
517 | } | 511 | } |
518 | } | 512 | } |
519 | __psycho_check_stc_error(p, afsr, afar, type); | 513 | __psycho_check_stc_error(pbm, afsr, afar, type); |
520 | spin_unlock_irqrestore(&iommu->lock, flags); | 514 | spin_unlock_irqrestore(&iommu->lock, flags); |
521 | } | 515 | } |
522 | 516 | ||
@@ -541,9 +535,10 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
541 | 535 | ||
542 | static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | 536 | static irqreturn_t psycho_ue_intr(int irq, void *dev_id) |
543 | { | 537 | { |
544 | struct pci_controller_info *p = dev_id; | 538 | struct pci_pbm_info *pbm = dev_id; |
545 | unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR; | 539 | struct pci_controller_info *p = pbm->parent; |
546 | unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFAR; | 540 | unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; |
541 | unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; | ||
547 | unsigned long afsr, afar, error_bits; | 542 | unsigned long afsr, afar, error_bits; |
548 | int reported; | 543 | int reported; |
549 | 544 | ||
@@ -593,8 +588,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | |||
593 | printk("(none)"); | 588 | printk("(none)"); |
594 | printk("]\n"); | 589 | printk("]\n"); |
595 | 590 | ||
596 | /* Interrogate IOMMU for error status. */ | 591 | /* Interrogate both IOMMUs for error status. */ |
597 | psycho_check_iommu_error(p, afsr, afar, UE_ERR); | 592 | psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR); |
593 | psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR); | ||
598 | 594 | ||
599 | return IRQ_HANDLED; | 595 | return IRQ_HANDLED; |
600 | } | 596 | } |
@@ -618,9 +614,10 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | |||
618 | 614 | ||
619 | static irqreturn_t psycho_ce_intr(int irq, void *dev_id) | 615 | static irqreturn_t psycho_ce_intr(int irq, void *dev_id) |
620 | { | 616 | { |
621 | struct pci_controller_info *p = dev_id; | 617 | struct pci_pbm_info *pbm = dev_id; |
622 | unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR; | 618 | struct pci_controller_info *p = pbm->parent; |
623 | unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFAR; | 619 | unsigned long afsr_reg = pbm->controller_regs + PSYCHO_CE_AFSR; |
620 | unsigned long afar_reg = pbm->controller_regs + PSYCHO_CE_AFAR; | ||
624 | unsigned long afsr, afar, error_bits; | 621 | unsigned long afsr, afar, error_bits; |
625 | int reported; | 622 | int reported; |
626 | 623 | ||
@@ -823,11 +820,11 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
823 | * a bug in the IOMMU support code or a PCI device driver. | 820 | * a bug in the IOMMU support code or a PCI device driver. |
824 | */ | 821 | */ |
825 | if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) { | 822 | if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) { |
826 | psycho_check_iommu_error(p, afsr, afar, PCI_ERR); | 823 | psycho_check_iommu_error(pbm, afsr, afar, PCI_ERR); |
827 | pci_scan_for_target_abort(p, pbm, pbm->pci_bus); | 824 | pci_scan_for_target_abort(pbm->parent, pbm, pbm->pci_bus); |
828 | } | 825 | } |
829 | if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA)) | 826 | if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA)) |
830 | pci_scan_for_master_abort(p, pbm, pbm->pci_bus); | 827 | pci_scan_for_master_abort(pbm->parent, pbm, pbm->pci_bus); |
831 | 828 | ||
832 | /* For excessive retries, PSYCHO/PBM will abort the device | 829 | /* For excessive retries, PSYCHO/PBM will abort the device |
833 | * and there is no way to specifically check for excessive | 830 | * and there is no way to specifically check for excessive |
@@ -837,7 +834,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
837 | */ | 834 | */ |
838 | 835 | ||
839 | if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR)) | 836 | if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR)) |
840 | pci_scan_for_parity_error(p, pbm, pbm->pci_bus); | 837 | pci_scan_for_parity_error(pbm->parent, pbm, pbm->pci_bus); |
841 | 838 | ||
842 | return IRQ_HANDLED; | 839 | return IRQ_HANDLED; |
843 | } | 840 | } |
@@ -847,34 +844,33 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
847 | #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ | 844 | #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ |
848 | #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ | 845 | #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ |
849 | #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ | 846 | #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ |
850 | static void psycho_register_error_handlers(struct pci_controller_info *p) | 847 | static void psycho_register_error_handlers(struct pci_pbm_info *pbm) |
851 | { | 848 | { |
852 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ | ||
853 | struct of_device *op = of_find_device_by_node(pbm->prom_node); | 849 | struct of_device *op = of_find_device_by_node(pbm->prom_node); |
854 | unsigned long base = p->pbm_A.controller_regs; | 850 | unsigned long base = pbm->controller_regs; |
855 | u64 tmp; | 851 | u64 tmp; |
856 | 852 | ||
857 | if (!op) | 853 | if (!op) |
858 | return; | 854 | return; |
859 | 855 | ||
860 | /* Psycho interrupt property order is: | 856 | /* Psycho interrupt property order is: |
861 | * 0: PCIERR PBM B INO | 857 | * 0: PCIERR INO for this PBM |
862 | * 1: UE ERR | 858 | * 1: UE ERR |
863 | * 2: CE ERR | 859 | * 2: CE ERR |
864 | * 3: POWER FAIL | 860 | * 3: POWER FAIL |
865 | * 4: SPARE HARDWARE | 861 | * 4: SPARE HARDWARE |
866 | * 5: PCIERR PBM A INO | 862 | * 5: POWER MANAGEMENT |
867 | */ | 863 | */ |
868 | 864 | ||
869 | if (op->num_irqs < 6) | 865 | if (op->num_irqs < 6) |
870 | return; | 866 | return; |
871 | 867 | ||
872 | request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED, "PSYCHO UE", p); | 868 | request_irq(op->irqs[1], psycho_ue_intr, 0, |
873 | request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED, "PSYCHO CE", p); | 869 | "PSYCHO_UE", pbm); |
874 | request_irq(op->irqs[5], psycho_pcierr_intr, IRQF_SHARED, | 870 | request_irq(op->irqs[2], psycho_ce_intr, 0, |
875 | "PSYCHO PCIERR-A", &p->pbm_A); | 871 | "PSYCHO_CE", pbm); |
876 | request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED, | 872 | request_irq(op->irqs[0], psycho_pcierr_intr, 0, |
877 | "PSYCHO PCIERR-B", &p->pbm_B); | 873 | "PSYCHO_PCIERR", pbm); |
878 | 874 | ||
879 | /* Enable UE and CE interrupts for controller. */ | 875 | /* Enable UE and CE interrupts for controller. */ |
880 | psycho_write(base + PSYCHO_ECC_CTRL, | 876 | psycho_write(base + PSYCHO_ECC_CTRL, |
@@ -918,25 +914,16 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
918 | pci_config_write8(addr, 64); | 914 | pci_config_write8(addr, 64); |
919 | } | 915 | } |
920 | 916 | ||
921 | static void pbm_scan_bus(struct pci_controller_info *p, | 917 | static void psycho_scan_bus(struct pci_pbm_info *pbm) |
922 | struct pci_pbm_info *pbm) | ||
923 | { | 918 | { |
919 | pbm_config_busmastering(pbm); | ||
920 | pbm->is_66mhz_capable = 0; | ||
924 | pbm->pci_bus = pci_scan_one_pbm(pbm); | 921 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
925 | } | ||
926 | |||
927 | static void psycho_scan_bus(struct pci_controller_info *p) | ||
928 | { | ||
929 | pbm_config_busmastering(&p->pbm_B); | ||
930 | p->pbm_B.is_66mhz_capable = 0; | ||
931 | pbm_config_busmastering(&p->pbm_A); | ||
932 | p->pbm_A.is_66mhz_capable = 1; | ||
933 | pbm_scan_bus(p, &p->pbm_B); | ||
934 | pbm_scan_bus(p, &p->pbm_A); | ||
935 | 922 | ||
936 | /* After the PCI bus scan is complete, we can register | 923 | /* After the PCI bus scan is complete, we can register |
937 | * the error interrupt handlers. | 924 | * the error interrupt handlers. |
938 | */ | 925 | */ |
939 | psycho_register_error_handlers(p); | 926 | psycho_register_error_handlers(pbm); |
940 | } | 927 | } |
941 | 928 | ||
942 | static void psycho_iommu_init(struct pci_controller_info *p) | 929 | static void psycho_iommu_init(struct pci_controller_info *p) |
@@ -1096,6 +1083,11 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1096 | else | 1083 | else |
1097 | pbm = &p->pbm_B; | 1084 | pbm = &p->pbm_B; |
1098 | 1085 | ||
1086 | pbm->next = pci_pbm_root; | ||
1087 | pci_pbm_root = pbm; | ||
1088 | |||
1089 | pbm->scan_bus = psycho_scan_bus; | ||
1090 | |||
1099 | pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; | 1091 | pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; |
1100 | pbm->chip_version = 0; | 1092 | pbm->chip_version = 0; |
1101 | prop = of_find_property(dp, "version#", NULL); | 1093 | prop = of_find_property(dp, "version#", NULL); |
@@ -1127,6 +1119,7 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1127 | { | 1119 | { |
1128 | struct linux_prom64_registers *pr_regs; | 1120 | struct linux_prom64_registers *pr_regs; |
1129 | struct pci_controller_info *p; | 1121 | struct pci_controller_info *p; |
1122 | struct pci_pbm_info *pbm; | ||
1130 | struct iommu *iommu; | 1123 | struct iommu *iommu; |
1131 | struct property *prop; | 1124 | struct property *prop; |
1132 | u32 upa_portid; | 1125 | u32 upa_portid; |
@@ -1137,7 +1130,9 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1137 | if (prop) | 1130 | if (prop) |
1138 | upa_portid = *(u32 *) prop->value; | 1131 | upa_portid = *(u32 *) prop->value; |
1139 | 1132 | ||
1140 | for(p = pci_controller_root; p; p = p->next) { | 1133 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1134 | struct pci_controller_info *p = pbm->parent; | ||
1135 | |||
1141 | if (p->pbm_A.portid == upa_portid) { | 1136 | if (p->pbm_A.portid == upa_portid) { |
1142 | is_pbm_a = (p->pbm_A.prom_node == NULL); | 1137 | is_pbm_a = (p->pbm_A.prom_node == NULL); |
1143 | psycho_pbm_init(p, dp, is_pbm_a); | 1138 | psycho_pbm_init(p, dp, is_pbm_a); |
@@ -1157,13 +1152,9 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1157 | } | 1152 | } |
1158 | p->pbm_A.iommu = p->pbm_B.iommu = iommu; | 1153 | p->pbm_A.iommu = p->pbm_B.iommu = iommu; |
1159 | 1154 | ||
1160 | p->next = pci_controller_root; | ||
1161 | pci_controller_root = p; | ||
1162 | |||
1163 | p->pbm_A.portid = upa_portid; | 1155 | p->pbm_A.portid = upa_portid; |
1164 | p->pbm_B.portid = upa_portid; | 1156 | p->pbm_B.portid = upa_portid; |
1165 | p->index = pci_num_controllers++; | 1157 | p->index = pci_num_controllers++; |
1166 | p->scan_bus = psycho_scan_bus; | ||
1167 | p->pci_ops = &psycho_ops; | 1158 | p->pci_ops = &psycho_ops; |
1168 | 1159 | ||
1169 | prop = of_find_property(dp, "reg", NULL); | 1160 | prop = of_find_property(dp, "reg", NULL); |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 9e706013d11a..024dbd8ad025 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -825,9 +825,9 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
825 | return IRQ_HANDLED; | 825 | return IRQ_HANDLED; |
826 | } | 826 | } |
827 | 827 | ||
828 | static void sabre_register_error_handlers(struct pci_controller_info *p) | 828 | static void sabre_register_error_handlers(struct pci_pbm_info *pbm) |
829 | { | 829 | { |
830 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ | 830 | struct pci_controller_info *p = pbm->parent; |
831 | struct device_node *dp = pbm->prom_node; | 831 | struct device_node *dp = pbm->prom_node; |
832 | struct of_device *op; | 832 | struct of_device *op; |
833 | unsigned long base = pbm->controller_regs; | 833 | unsigned long base = pbm->controller_regs; |
@@ -858,22 +858,22 @@ static void sabre_register_error_handlers(struct pci_controller_info *p) | |||
858 | SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | | 858 | SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | |
859 | SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); | 859 | SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); |
860 | 860 | ||
861 | request_irq(op->irqs[1], sabre_ue_intr, IRQF_SHARED, "SABRE UE", p); | 861 | request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", p); |
862 | 862 | ||
863 | sabre_write(base + SABRE_CE_AFSR, | 863 | sabre_write(base + SABRE_CE_AFSR, |
864 | (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | | 864 | (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | |
865 | SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); | 865 | SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); |
866 | 866 | ||
867 | request_irq(op->irqs[2], sabre_ce_intr, IRQF_SHARED, "SABRE CE", p); | 867 | request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", p); |
868 | request_irq(op->irqs[0], sabre_pcierr_intr, IRQF_SHARED, | 868 | request_irq(op->irqs[0], sabre_pcierr_intr, 0, |
869 | "SABRE PCIERR", p); | 869 | "SABRE_PCIERR", p); |
870 | 870 | ||
871 | tmp = sabre_read(base + SABRE_PCICTRL); | 871 | tmp = sabre_read(base + SABRE_PCICTRL); |
872 | tmp |= SABRE_PCICTRL_ERREN; | 872 | tmp |= SABRE_PCICTRL_ERREN; |
873 | sabre_write(base + SABRE_PCICTRL, tmp); | 873 | sabre_write(base + SABRE_PCICTRL, tmp); |
874 | } | 874 | } |
875 | 875 | ||
876 | static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) | 876 | static void apb_init(struct pci_bus *sabre_bus) |
877 | { | 877 | { |
878 | struct pci_dev *pdev; | 878 | struct pci_dev *pdev; |
879 | 879 | ||
@@ -909,7 +909,7 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) | |||
909 | } | 909 | } |
910 | } | 910 | } |
911 | 911 | ||
912 | static void sabre_scan_bus(struct pci_controller_info *p) | 912 | static void sabre_scan_bus(struct pci_pbm_info *pbm) |
913 | { | 913 | { |
914 | static int once; | 914 | static int once; |
915 | struct pci_bus *pbus; | 915 | struct pci_bus *pbus; |
@@ -918,7 +918,7 @@ static void sabre_scan_bus(struct pci_controller_info *p) | |||
918 | * at 66Mhz, but the front side of APB runs at 33Mhz | 918 | * at 66Mhz, but the front side of APB runs at 33Mhz |
919 | * for both segments. | 919 | * for both segments. |
920 | */ | 920 | */ |
921 | p->pbm_A.is_66mhz_capable = 0; | 921 | pbm->is_66mhz_capable = 0; |
922 | 922 | ||
923 | /* This driver has not been verified to handle | 923 | /* This driver has not been verified to handle |
924 | * multiple SABREs yet, so trap this. | 924 | * multiple SABREs yet, so trap this. |
@@ -932,15 +932,15 @@ static void sabre_scan_bus(struct pci_controller_info *p) | |||
932 | } | 932 | } |
933 | once++; | 933 | once++; |
934 | 934 | ||
935 | pbus = pci_scan_one_pbm(&p->pbm_A); | 935 | pbus = pci_scan_one_pbm(pbm); |
936 | if (!pbus) | 936 | if (!pbus) |
937 | return; | 937 | return; |
938 | 938 | ||
939 | sabre_root_bus = pbus; | 939 | sabre_root_bus = pbus; |
940 | 940 | ||
941 | apb_init(p, pbus); | 941 | apb_init(pbus); |
942 | 942 | ||
943 | sabre_register_error_handlers(p); | 943 | sabre_register_error_handlers(pbm); |
944 | } | 944 | } |
945 | 945 | ||
946 | static void sabre_iommu_init(struct pci_controller_info *p, | 946 | static void sabre_iommu_init(struct pci_controller_info *p, |
@@ -1003,6 +1003,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp | |||
1003 | pbm->name = dp->full_name; | 1003 | pbm->name = dp->full_name; |
1004 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | 1004 | printk("%s: SABRE PCI Bus Module\n", pbm->name); |
1005 | 1005 | ||
1006 | pbm->scan_bus = sabre_scan_bus; | ||
1007 | |||
1006 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; | 1008 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; |
1007 | pbm->parent = p; | 1009 | pbm->parent = p; |
1008 | pbm->prom_node = dp; | 1010 | pbm->prom_node = dp; |
@@ -1055,12 +1057,11 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1055 | 1057 | ||
1056 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); | 1058 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); |
1057 | 1059 | ||
1058 | p->next = pci_controller_root; | 1060 | p->pbm_A.next = pci_pbm_root; |
1059 | pci_controller_root = p; | 1061 | pci_pbm_root = &p->pbm_A; |
1060 | 1062 | ||
1061 | p->pbm_A.portid = upa_portid; | 1063 | p->pbm_A.portid = upa_portid; |
1062 | p->index = pci_num_controllers++; | 1064 | p->index = pci_num_controllers++; |
1063 | p->scan_bus = sabre_scan_bus; | ||
1064 | p->pci_ops = &sabre_ops; | 1065 | p->pci_ops = &sabre_ops; |
1065 | 1066 | ||
1066 | /* | 1067 | /* |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index c0a6a3866e2f..4ebdcbd5262a 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -238,25 +238,6 @@ static unsigned long stc_line_buf[16]; | |||
238 | #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ | 238 | #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ |
239 | #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ | 239 | #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ |
240 | 240 | ||
241 | struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) | ||
242 | { | ||
243 | ino &= IMAP_INO; | ||
244 | if (p->pbm_A.ino_bitmap & (1UL << ino)) | ||
245 | return &p->pbm_A; | ||
246 | if (p->pbm_B.ino_bitmap & (1UL << ino)) | ||
247 | return &p->pbm_B; | ||
248 | |||
249 | printk("PCI%d: No ino_bitmap entry for ino[%x], bitmaps " | ||
250 | "PBM_A[%016lx] PBM_B[%016lx]", | ||
251 | p->index, ino, | ||
252 | p->pbm_A.ino_bitmap, | ||
253 | p->pbm_B.ino_bitmap); | ||
254 | printk("PCI%d: Using PBM_A, report this problem immediately.\n", | ||
255 | p->index); | ||
256 | |||
257 | return &p->pbm_A; | ||
258 | } | ||
259 | |||
260 | #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ | 241 | #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ |
261 | #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ | 242 | #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ |
262 | #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ | 243 | #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ |
@@ -522,9 +503,10 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, | |||
522 | 503 | ||
523 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | 504 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) |
524 | { | 505 | { |
525 | struct pci_controller_info *p = dev_id; | 506 | struct pci_pbm_info *pbm = dev_id; |
526 | unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR; | 507 | struct pci_controller_info *p = pbm->parent; |
527 | unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFAR; | 508 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; |
509 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; | ||
528 | unsigned long afsr, afar, error_bits; | 510 | unsigned long afsr, afar, error_bits; |
529 | int reported, limit; | 511 | int reported, limit; |
530 | 512 | ||
@@ -610,9 +592,10 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | |||
610 | 592 | ||
611 | static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | 593 | static irqreturn_t schizo_ce_intr(int irq, void *dev_id) |
612 | { | 594 | { |
613 | struct pci_controller_info *p = dev_id; | 595 | struct pci_pbm_info *pbm = dev_id; |
614 | unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR; | 596 | struct pci_controller_info *p = pbm->parent; |
615 | unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFAR; | 597 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_CE_AFSR; |
598 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_CE_AFAR; | ||
616 | unsigned long afsr, afar, error_bits; | 599 | unsigned long afsr, afar, error_bits; |
617 | int reported, limit; | 600 | int reported, limit; |
618 | 601 | ||
@@ -940,11 +923,12 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
940 | */ | 923 | */ |
941 | static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | 924 | static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) |
942 | { | 925 | { |
943 | struct pci_controller_info *p = dev_id; | 926 | struct pci_pbm_info *pbm = dev_id; |
927 | struct pci_controller_info *p = pbm->parent; | ||
944 | u64 errlog; | 928 | u64 errlog; |
945 | 929 | ||
946 | errlog = schizo_read(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG); | 930 | errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); |
947 | schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG, | 931 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG, |
948 | errlog & ~(SAFARI_ERRLOG_ERROUT)); | 932 | errlog & ~(SAFARI_ERRLOG_ERROUT)); |
949 | 933 | ||
950 | if (!(errlog & BUS_ERROR_UNMAP)) { | 934 | if (!(errlog & BUS_ERROR_UNMAP)) { |
@@ -972,6 +956,16 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | |||
972 | #define SCHIZO_SAFARI_IRQCTRL 0x10010UL | 956 | #define SCHIZO_SAFARI_IRQCTRL 0x10010UL |
973 | #define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL | 957 | #define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL |
974 | 958 | ||
959 | static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) | ||
960 | { | ||
961 | ino &= IMAP_INO; | ||
962 | |||
963 | if (pbm->ino_bitmap & (1UL << ino)) | ||
964 | return 1; | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
975 | /* How the Tomatillo IRQs are routed around is pure guesswork here. | 969 | /* How the Tomatillo IRQs are routed around is pure guesswork here. |
976 | * | 970 | * |
977 | * All the Tomatillo devices I see in prtconf dumps seem to have only | 971 | * All the Tomatillo devices I see in prtconf dumps seem to have only |
@@ -986,10 +980,9 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) | |||
986 | * PCI bus units of the same Tomatillo. I still have not really | 980 | * PCI bus units of the same Tomatillo. I still have not really |
987 | * figured this out... | 981 | * figured this out... |
988 | */ | 982 | */ |
989 | static void tomatillo_register_error_handlers(struct pci_controller_info *p) | 983 | static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) |
990 | { | 984 | { |
991 | struct pci_pbm_info *pbm; | 985 | struct of_device *op = of_find_device_by_node(pbm->prom_node); |
992 | struct of_device *op; | ||
993 | u64 tmp, err_mask, err_no_mask; | 986 | u64 tmp, err_mask, err_no_mask; |
994 | 987 | ||
995 | /* Tomatillo IRQ property layout is: | 988 | /* Tomatillo IRQ property layout is: |
@@ -1000,44 +993,27 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1000 | * 4: POWER FAIL? | 993 | * 4: POWER FAIL? |
1001 | */ | 994 | */ |
1002 | 995 | ||
1003 | pbm = pbm_for_ino(p, SCHIZO_UE_INO); | 996 | if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) |
1004 | op = of_find_device_by_node(pbm->prom_node); | 997 | request_irq(op->irqs[1], schizo_ue_intr, 0, |
1005 | if (op) | 998 | "TOMATILLO_UE", pbm); |
1006 | request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, | ||
1007 | "TOMATILLO_UE", p); | ||
1008 | |||
1009 | pbm = pbm_for_ino(p, SCHIZO_CE_INO); | ||
1010 | op = of_find_device_by_node(pbm->prom_node); | ||
1011 | if (op) | ||
1012 | request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, | ||
1013 | "TOMATILLO CE", p); | ||
1014 | |||
1015 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); | ||
1016 | op = of_find_device_by_node(pbm->prom_node); | ||
1017 | if (op) | ||
1018 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | ||
1019 | "TOMATILLO PCIERR-A", pbm); | ||
1020 | |||
1021 | |||
1022 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); | ||
1023 | op = of_find_device_by_node(pbm->prom_node); | ||
1024 | if (op) | ||
1025 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | ||
1026 | "TOMATILLO PCIERR-B", pbm); | ||
1027 | |||
1028 | pbm = pbm_for_ino(p, SCHIZO_SERR_INO); | ||
1029 | op = of_find_device_by_node(pbm->prom_node); | ||
1030 | if (op) | ||
1031 | request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, | ||
1032 | "TOMATILLO SERR", p); | ||
1033 | 999 | ||
1034 | /* Enable UE and CE interrupts for controller. */ | 1000 | if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) |
1035 | schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, | 1001 | request_irq(op->irqs[2], schizo_ce_intr, 0, |
1036 | (SCHIZO_ECCCTRL_EE | | 1002 | "TOMATILLO_CE", pbm); |
1037 | SCHIZO_ECCCTRL_UE | | 1003 | |
1038 | SCHIZO_ECCCTRL_CE)); | 1004 | if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) |
1005 | request_irq(op->irqs[0], schizo_pcierr_intr, 0, | ||
1006 | "TOMATILLO_PCIERR", pbm); | ||
1007 | else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) | ||
1008 | request_irq(op->irqs[0], schizo_pcierr_intr, 0, | ||
1009 | "TOMATILLO_PCIERR", pbm); | ||
1039 | 1010 | ||
1040 | schizo_write(p->pbm_B.controller_regs + SCHIZO_ECC_CTRL, | 1011 | if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) |
1012 | request_irq(op->irqs[3], schizo_safarierr_intr, 0, | ||
1013 | "TOMATILLO_SERR", pbm); | ||
1014 | |||
1015 | /* Enable UE and CE interrupts for controller. */ | ||
1016 | schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, | ||
1041 | (SCHIZO_ECCCTRL_EE | | 1017 | (SCHIZO_ECCCTRL_EE | |
1042 | SCHIZO_ECCCTRL_UE | | 1018 | SCHIZO_ECCCTRL_UE | |
1043 | SCHIZO_ECCCTRL_CE)); | 1019 | SCHIZO_ECCCTRL_CE)); |
@@ -1053,15 +1029,10 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1053 | 1029 | ||
1054 | err_no_mask = SCHIZO_PCICTRL_DTO_ERR; | 1030 | err_no_mask = SCHIZO_PCICTRL_DTO_ERR; |
1055 | 1031 | ||
1056 | tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); | 1032 | tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); |
1057 | tmp |= err_mask; | ||
1058 | tmp &= ~err_no_mask; | ||
1059 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); | ||
1060 | |||
1061 | tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); | ||
1062 | tmp |= err_mask; | 1033 | tmp |= err_mask; |
1063 | tmp &= ~err_no_mask; | 1034 | tmp &= ~err_no_mask; |
1064 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); | 1035 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); |
1065 | 1036 | ||
1066 | err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | 1037 | err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | |
1067 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | 1038 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | |
@@ -1070,8 +1041,7 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1070 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | | 1041 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | |
1071 | SCHIZO_PCIAFSR_STTO); | 1042 | SCHIZO_PCIAFSR_STTO); |
1072 | 1043 | ||
1073 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, err_mask); | 1044 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, err_mask); |
1074 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, err_mask); | ||
1075 | 1045 | ||
1076 | err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | | 1046 | err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | |
1077 | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | | 1047 | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | |
@@ -1083,21 +1053,16 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1083 | BUS_ERROR_APERR | BUS_ERROR_UNMAP | | 1053 | BUS_ERROR_APERR | BUS_ERROR_UNMAP | |
1084 | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); | 1054 | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); |
1085 | 1055 | ||
1086 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, | 1056 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, |
1087 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | ||
1088 | schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRCTRL, | ||
1089 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | 1057 | (SCHIZO_SAFERRCTRL_EN | err_mask)); |
1090 | 1058 | ||
1091 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, | 1059 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_IRQCTRL, |
1092 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | ||
1093 | schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_IRQCTRL, | ||
1094 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | 1060 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); |
1095 | } | 1061 | } |
1096 | 1062 | ||
1097 | static void schizo_register_error_handlers(struct pci_controller_info *p) | 1063 | static void schizo_register_error_handlers(struct pci_pbm_info *pbm) |
1098 | { | 1064 | { |
1099 | struct pci_pbm_info *pbm; | 1065 | struct of_device *op = of_find_device_by_node(pbm->prom_node); |
1100 | struct of_device *op; | ||
1101 | u64 tmp, err_mask, err_no_mask; | 1066 | u64 tmp, err_mask, err_no_mask; |
1102 | 1067 | ||
1103 | /* Schizo IRQ property layout is: | 1068 | /* Schizo IRQ property layout is: |
@@ -1108,39 +1073,27 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1108 | * 4: POWER FAIL? | 1073 | * 4: POWER FAIL? |
1109 | */ | 1074 | */ |
1110 | 1075 | ||
1111 | pbm = pbm_for_ino(p, SCHIZO_UE_INO); | 1076 | if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) |
1112 | op = of_find_device_by_node(pbm->prom_node); | 1077 | request_irq(op->irqs[1], schizo_ue_intr, 0, |
1113 | if (op) | 1078 | "SCHIZO_UE", pbm); |
1114 | request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, | 1079 | |
1115 | "SCHIZO_UE", p); | 1080 | if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) |
1116 | 1081 | request_irq(op->irqs[2], schizo_ce_intr, 0, | |
1117 | pbm = pbm_for_ino(p, SCHIZO_CE_INO); | 1082 | "SCHIZO_CE", pbm); |
1118 | op = of_find_device_by_node(pbm->prom_node); | 1083 | |
1119 | if (op) | 1084 | if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) |
1120 | request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, | 1085 | request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1121 | "SCHIZO CE", p); | 1086 | "SCHIZO_PCIERR", pbm); |
1122 | 1087 | else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) | |
1123 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); | 1088 | request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1124 | op = of_find_device_by_node(pbm->prom_node); | 1089 | "SCHIZO_PCIERR", pbm); |
1125 | if (op) | 1090 | |
1126 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1091 | if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) |
1127 | "SCHIZO PCIERR-A", pbm); | 1092 | request_irq(op->irqs[3], schizo_safarierr_intr, 0, |
1128 | 1093 | "SCHIZO_SERR", pbm); | |
1129 | |||
1130 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); | ||
1131 | op = of_find_device_by_node(pbm->prom_node); | ||
1132 | if (op) | ||
1133 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | ||
1134 | "SCHIZO PCIERR-B", pbm); | ||
1135 | |||
1136 | pbm = pbm_for_ino(p, SCHIZO_SERR_INO); | ||
1137 | op = of_find_device_by_node(pbm->prom_node); | ||
1138 | if (op) | ||
1139 | request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, | ||
1140 | "SCHIZO SERR", p); | ||
1141 | 1094 | ||
1142 | /* Enable UE and CE interrupts for controller. */ | 1095 | /* Enable UE and CE interrupts for controller. */ |
1143 | schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, | 1096 | schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, |
1144 | (SCHIZO_ECCCTRL_EE | | 1097 | (SCHIZO_ECCCTRL_EE | |
1145 | SCHIZO_ECCCTRL_UE | | 1098 | SCHIZO_ECCCTRL_UE | |
1146 | SCHIZO_ECCCTRL_CE)); | 1099 | SCHIZO_ECCCTRL_CE)); |
@@ -1159,25 +1112,12 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1159 | /* Enable PCI Error interrupts and clear error | 1112 | /* Enable PCI Error interrupts and clear error |
1160 | * bits for each PBM. | 1113 | * bits for each PBM. |
1161 | */ | 1114 | */ |
1162 | tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); | 1115 | tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); |
1163 | tmp |= err_mask; | ||
1164 | tmp &= ~err_no_mask; | ||
1165 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); | ||
1166 | |||
1167 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, | ||
1168 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | ||
1169 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | ||
1170 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | | ||
1171 | SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | | ||
1172 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | | ||
1173 | SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); | ||
1174 | |||
1175 | tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); | ||
1176 | tmp |= err_mask; | 1116 | tmp |= err_mask; |
1177 | tmp &= ~err_no_mask; | 1117 | tmp &= ~err_no_mask; |
1178 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); | 1118 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); |
1179 | 1119 | ||
1180 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, | 1120 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, |
1181 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | 1121 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | |
1182 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | 1122 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | |
1183 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | | 1123 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | |
@@ -1210,11 +1150,8 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1210 | BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); | 1150 | BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); |
1211 | #endif | 1151 | #endif |
1212 | 1152 | ||
1213 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, | 1153 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, |
1214 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | 1154 | (SCHIZO_SAFERRCTRL_EN | err_mask)); |
1215 | |||
1216 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, | ||
1217 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); | ||
1218 | } | 1155 | } |
1219 | 1156 | ||
1220 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) | 1157 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) |
@@ -1234,27 +1171,19 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1234 | pci_config_write8(addr, 64); | 1171 | pci_config_write8(addr, 64); |
1235 | } | 1172 | } |
1236 | 1173 | ||
1237 | static void schizo_scan_bus(struct pci_controller_info *p) | 1174 | static void schizo_scan_bus(struct pci_pbm_info *pbm) |
1238 | { | 1175 | { |
1239 | pbm_config_busmastering(&p->pbm_B); | 1176 | pbm_config_busmastering(pbm); |
1240 | p->pbm_B.is_66mhz_capable = | 1177 | pbm->is_66mhz_capable = |
1241 | (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) | 1178 | (of_find_property(pbm->prom_node, "66mhz-capable", NULL) |
1242 | != NULL); | ||
1243 | pbm_config_busmastering(&p->pbm_A); | ||
1244 | p->pbm_A.is_66mhz_capable = | ||
1245 | (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL) | ||
1246 | != NULL); | 1179 | != NULL); |
1247 | 1180 | ||
1248 | p->pbm_B.pci_bus = pci_scan_one_pbm(&p->pbm_B); | 1181 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
1249 | p->pbm_A.pci_bus = pci_scan_one_pbm(&p->pbm_A); | ||
1250 | 1182 | ||
1251 | /* After the PCI bus scan is complete, we can register | 1183 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) |
1252 | * the error interrupt handlers. | 1184 | tomatillo_register_error_handlers(pbm); |
1253 | */ | ||
1254 | if (p->pbm_B.chip_type == PBM_CHIP_TYPE_TOMATILLO) | ||
1255 | tomatillo_register_error_handlers(p); | ||
1256 | else | 1185 | else |
1257 | schizo_register_error_handlers(p); | 1186 | schizo_register_error_handlers(pbm); |
1258 | } | 1187 | } |
1259 | 1188 | ||
1260 | #define SCHIZO_STRBUF_CONTROL (0x02800UL) | 1189 | #define SCHIZO_STRBUF_CONTROL (0x02800UL) |
@@ -1529,6 +1458,11 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1529 | else | 1458 | else |
1530 | pbm = &p->pbm_B; | 1459 | pbm = &p->pbm_B; |
1531 | 1460 | ||
1461 | pbm->next = pci_pbm_root; | ||
1462 | pci_pbm_root = pbm; | ||
1463 | |||
1464 | pbm->scan_bus = schizo_scan_bus; | ||
1465 | |||
1532 | pbm->portid = portid; | 1466 | pbm->portid = portid; |
1533 | pbm->parent = p; | 1467 | pbm->parent = p; |
1534 | pbm->prom_node = dp; | 1468 | pbm->prom_node = dp; |
@@ -1572,23 +1506,15 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1572 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) | 1506 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) |
1573 | { | 1507 | { |
1574 | struct pci_controller_info *p; | 1508 | struct pci_controller_info *p; |
1509 | struct pci_pbm_info *pbm; | ||
1575 | struct iommu *iommu; | 1510 | struct iommu *iommu; |
1576 | u32 portid; | 1511 | u32 portid; |
1577 | 1512 | ||
1578 | portid = of_getintprop_default(dp, "portid", 0xff); | 1513 | portid = of_getintprop_default(dp, "portid", 0xff); |
1579 | 1514 | ||
1580 | for (p = pci_controller_root; p; p = p->next) { | 1515 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1581 | struct pci_pbm_info *pbm; | ||
1582 | |||
1583 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
1584 | continue; | ||
1585 | |||
1586 | pbm = (p->pbm_A.prom_node ? | ||
1587 | &p->pbm_A : | ||
1588 | &p->pbm_B); | ||
1589 | |||
1590 | if (portid_compare(pbm->portid, portid, chip_type)) { | 1516 | if (portid_compare(pbm->portid, portid, chip_type)) { |
1591 | schizo_pbm_init(p, dp, portid, chip_type); | 1517 | schizo_pbm_init(pbm->parent, dp, portid, chip_type); |
1592 | return; | 1518 | return; |
1593 | } | 1519 | } |
1594 | } | 1520 | } |
@@ -1609,11 +1535,7 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ | |||
1609 | 1535 | ||
1610 | p->pbm_B.iommu = iommu; | 1536 | p->pbm_B.iommu = iommu; |
1611 | 1537 | ||
1612 | p->next = pci_controller_root; | ||
1613 | pci_controller_root = p; | ||
1614 | |||
1615 | p->index = pci_num_controllers++; | 1538 | p->index = pci_num_controllers++; |
1616 | p->scan_bus = schizo_scan_bus; | ||
1617 | p->pci_ops = &schizo_ops; | 1539 | p->pci_ops = &schizo_ops; |
1618 | 1540 | ||
1619 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ | 1541 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 1491ba330583..0a101cb22320 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -677,29 +677,15 @@ static struct pci_ops pci_sun4v_ops = { | |||
677 | }; | 677 | }; |
678 | 678 | ||
679 | 679 | ||
680 | static void pbm_scan_bus(struct pci_controller_info *p, | 680 | static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm) |
681 | struct pci_pbm_info *pbm) | ||
682 | { | ||
683 | pbm->pci_bus = pci_scan_one_pbm(pbm); | ||
684 | } | ||
685 | |||
686 | static void pci_sun4v_scan_bus(struct pci_controller_info *p) | ||
687 | { | 681 | { |
688 | struct property *prop; | 682 | struct property *prop; |
689 | struct device_node *dp; | 683 | struct device_node *dp; |
690 | 684 | ||
691 | if ((dp = p->pbm_A.prom_node) != NULL) { | 685 | dp = pbm->prom_node; |
692 | prop = of_find_property(dp, "66mhz-capable", NULL); | 686 | prop = of_find_property(dp, "66mhz-capable", NULL); |
693 | p->pbm_A.is_66mhz_capable = (prop != NULL); | 687 | pbm->is_66mhz_capable = (prop != NULL); |
694 | 688 | pbm->pci_bus = pci_scan_one_pbm(pbm); | |
695 | pbm_scan_bus(p, &p->pbm_A); | ||
696 | } | ||
697 | if ((dp = p->pbm_B.prom_node) != NULL) { | ||
698 | prop = of_find_property(dp, "66mhz-capable", NULL); | ||
699 | p->pbm_B.is_66mhz_capable = (prop != NULL); | ||
700 | |||
701 | pbm_scan_bus(p, &p->pbm_B); | ||
702 | } | ||
703 | 689 | ||
704 | /* XXX register error interrupt handlers XXX */ | 690 | /* XXX register error interrupt handlers XXX */ |
705 | } | 691 | } |
@@ -1246,6 +1232,11 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1246 | else | 1232 | else |
1247 | pbm = &p->pbm_A; | 1233 | pbm = &p->pbm_A; |
1248 | 1234 | ||
1235 | pbm->next = pci_pbm_root; | ||
1236 | pci_pbm_root = pbm; | ||
1237 | |||
1238 | pbm->scan_bus = pci_sun4v_scan_bus; | ||
1239 | |||
1249 | pbm->parent = p; | 1240 | pbm->parent = p; |
1250 | pbm->prom_node = dp; | 1241 | pbm->prom_node = dp; |
1251 | 1242 | ||
@@ -1265,6 +1256,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1265 | void sun4v_pci_init(struct device_node *dp, char *model_name) | 1256 | void sun4v_pci_init(struct device_node *dp, char *model_name) |
1266 | { | 1257 | { |
1267 | struct pci_controller_info *p; | 1258 | struct pci_controller_info *p; |
1259 | struct pci_pbm_info *pbm; | ||
1268 | struct iommu *iommu; | 1260 | struct iommu *iommu; |
1269 | struct property *prop; | 1261 | struct property *prop; |
1270 | struct linux_prom64_registers *regs; | 1262 | struct linux_prom64_registers *regs; |
@@ -1276,18 +1268,9 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) | |||
1276 | 1268 | ||
1277 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; | 1269 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; |
1278 | 1270 | ||
1279 | for (p = pci_controller_root; p; p = p->next) { | 1271 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1280 | struct pci_pbm_info *pbm; | ||
1281 | |||
1282 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
1283 | continue; | ||
1284 | |||
1285 | pbm = (p->pbm_A.prom_node ? | ||
1286 | &p->pbm_A : | ||
1287 | &p->pbm_B); | ||
1288 | |||
1289 | if (pbm->devhandle == (devhandle ^ 0x40)) { | 1272 | if (pbm->devhandle == (devhandle ^ 0x40)) { |
1290 | pci_sun4v_pbm_init(p, dp, devhandle); | 1273 | pci_sun4v_pbm_init(pbm->parent, dp, devhandle); |
1291 | return; | 1274 | return; |
1292 | } | 1275 | } |
1293 | } | 1276 | } |
@@ -1317,12 +1300,8 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) | |||
1317 | 1300 | ||
1318 | p->pbm_B.iommu = iommu; | 1301 | p->pbm_B.iommu = iommu; |
1319 | 1302 | ||
1320 | p->next = pci_controller_root; | ||
1321 | pci_controller_root = p; | ||
1322 | |||
1323 | p->index = pci_num_controllers++; | 1303 | p->index = pci_num_controllers++; |
1324 | 1304 | ||
1325 | p->scan_bus = pci_sun4v_scan_bus; | ||
1326 | #ifdef CONFIG_PCI_MSI | 1305 | #ifdef CONFIG_PCI_MSI |
1327 | p->setup_msi_irq = pci_sun4v_setup_msi_irq; | 1306 | p->setup_msi_irq = pci_sun4v_setup_msi_irq; |
1328 | p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; | 1307 | p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; |
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index c8868babc4fe..cc0e2677773f 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h | |||
@@ -39,6 +39,8 @@ extern void pci_iommu_table_init(struct iommu *iommu, int tsbsize, u32 dma_offse | |||
39 | struct pci_controller_info; | 39 | struct pci_controller_info; |
40 | 40 | ||
41 | struct pci_pbm_info { | 41 | struct pci_pbm_info { |
42 | struct pci_pbm_info *next; | ||
43 | |||
42 | /* PCI controller we sit under. */ | 44 | /* PCI controller we sit under. */ |
43 | struct pci_controller_info *parent; | 45 | struct pci_controller_info *parent; |
44 | 46 | ||
@@ -113,12 +115,10 @@ struct pci_pbm_info { | |||
113 | unsigned int pci_first_busno; | 115 | unsigned int pci_first_busno; |
114 | unsigned int pci_last_busno; | 116 | unsigned int pci_last_busno; |
115 | struct pci_bus *pci_bus; | 117 | struct pci_bus *pci_bus; |
118 | void (*scan_bus)(struct pci_pbm_info *); | ||
116 | }; | 119 | }; |
117 | 120 | ||
118 | struct pci_controller_info { | 121 | struct pci_controller_info { |
119 | /* List of all PCI controllers. */ | ||
120 | struct pci_controller_info *next; | ||
121 | |||
122 | /* Each controller gets a unique index, used mostly for | 122 | /* Each controller gets a unique index, used mostly for |
123 | * error logging purposes. | 123 | * error logging purposes. |
124 | */ | 124 | */ |
@@ -129,8 +129,6 @@ struct pci_controller_info { | |||
129 | struct pci_pbm_info pbm_B; | 129 | struct pci_pbm_info pbm_B; |
130 | 130 | ||
131 | /* Operations which are controller specific. */ | 131 | /* Operations which are controller specific. */ |
132 | void (*scan_bus)(struct pci_controller_info *); | ||
133 | |||
134 | #ifdef CONFIG_PCI_MSI | 132 | #ifdef CONFIG_PCI_MSI |
135 | int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, | 133 | int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, |
136 | struct msi_desc *entry); | 134 | struct msi_desc *entry); |