diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 23:32:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 23:32:43 -0400 |
commit | 0c23664ee8c42f247dba7ceb620baabd892cef88 (patch) | |
tree | e3f37e3260bd938b293cfb8f70f8969b19539973 /arch | |
parent | 6ec129c3a2f8b38bc37e42348470ccfcb7460146 (diff) | |
parent | 127cda1e8cc282de1ca7a9dcc3866841977b9fcc (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Optimize fault kprobe handling just like powerpc.
[SPARC]: Wire up utimensat syscall.
[SPARC64]: Fix request_irq() ignored result warnings in PCI controller code.
[SPARC64]: Kill asm-sparc64/pbm.h
[ATYFB]: Fix sparc includes.
[QLA2XXX]: Fix build on sparc.
[SPARC64]: Removal of trivial pci_controller_info uses.
[SPARC64]: Move index info pci_pbm_info.
[SPARC64]: Move {setup,teardown}_msi_irq into pci_pbm_info.
[SPARC64]: Move pci_ops into pci_pbm_info.
[SPARC64] SBUS: Error interrupt registry cleanups.
[SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's
[SPARC64] PCI: Kill PROM_PCIRNG_MAX and PROM_PCIIMAP_MAX.
[SPARC64] PCI: Use common routine to fetch PBM properties.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/kernel/systbls.S | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/ebus.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/kprobes.c | 11 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci.c | 45 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_common.c | 46 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_fire.c | 56 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_impl.h | 124 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_iommu.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 264 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 204 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 352 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 294 | ||||
-rw-r--r-- | arch/sparc64/kernel/sbus.c | 12 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/systbls.S | 3 | ||||
-rw-r--r-- | arch/sparc64/mm/fault.c | 45 |
16 files changed, 716 insertions, 751 deletions
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 3a69778c8366..e3f5b8ed4c52 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
@@ -80,6 +80,7 @@ sys_call_table: | |||
80 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 80 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
81 | /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy | 81 | /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy |
82 | /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 82 | /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
83 | /*310*/ .long sys_utimensat | ||
83 | 84 | ||
84 | #ifdef CONFIG_SUNOS_EMUL | 85 | #ifdef CONFIG_SUNOS_EMUL |
85 | /* Now the SunOS syscall table. */ | 86 | /* Now the SunOS syscall table. */ |
@@ -196,5 +197,6 @@ sunos_sys_table: | |||
196 | .long sunos_nosys, sunos_nosys, sunos_nosys | 197 | .long sunos_nosys, sunos_nosys, sunos_nosys |
197 | .long sunos_nosys, sunos_nosys, sunos_nosys | 198 | .long sunos_nosys, sunos_nosys, sunos_nosys |
198 | .long sunos_nosys | 199 | .long sunos_nosys |
200 | /*310*/ .long sunos_nosys | ||
199 | 201 | ||
200 | #endif | 202 | #endif |
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 0ace17bafba4..ad55a9bb50dd 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c | |||
@@ -13,16 +13,17 @@ | |||
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/pci.h> | ||
16 | 17 | ||
17 | #include <asm/system.h> | 18 | #include <asm/system.h> |
18 | #include <asm/page.h> | 19 | #include <asm/page.h> |
19 | #include <asm/pbm.h> | ||
20 | #include <asm/ebus.h> | 20 | #include <asm/ebus.h> |
21 | #include <asm/oplib.h> | 21 | #include <asm/oplib.h> |
22 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
23 | #include <asm/of_device.h> | 23 | #include <asm/of_device.h> |
24 | #include <asm/bpp.h> | 24 | #include <asm/bpp.h> |
25 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
26 | #include <asm/io.h> | ||
26 | 27 | ||
27 | /* EBUS dma library. */ | 28 | /* EBUS dma library. */ |
28 | 29 | ||
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index a44fe47a3c2b..c93a15b785fa 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c | |||
@@ -313,7 +313,7 @@ out: | |||
313 | return 1; | 313 | return 1; |
314 | } | 314 | } |
315 | 315 | ||
316 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 316 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
317 | { | 317 | { |
318 | struct kprobe *cur = kprobe_running(); | 318 | struct kprobe *cur = kprobe_running(); |
319 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 319 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -403,15 +403,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
403 | if (post_kprobe_handler(args->regs)) | 403 | if (post_kprobe_handler(args->regs)) |
404 | ret = NOTIFY_STOP; | 404 | ret = NOTIFY_STOP; |
405 | break; | 405 | break; |
406 | case DIE_GPF: | ||
407 | case DIE_PAGE_FAULT: | ||
408 | /* kprobe_running() needs smp_processor_id() */ | ||
409 | preempt_disable(); | ||
410 | if (kprobe_running() && | ||
411 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
412 | ret = NOTIFY_STOP; | ||
413 | preempt_enable(); | ||
414 | break; | ||
415 | default: | 406 | default: |
416 | break; | 407 | break; |
417 | } | 408 | } |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 966861b212be..d85e1ed7c3e4 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -14,12 +14,12 @@ | |||
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/capability.h> | 15 | #include <linux/capability.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/pci.h> | ||
17 | #include <linux/msi.h> | 18 | #include <linux/msi.h> |
18 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
20 | 21 | ||
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
22 | #include <asm/pbm.h> | ||
23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
24 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
25 | #include <asm/ebus.h> | 25 | #include <asm/ebus.h> |
@@ -48,10 +48,10 @@ 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 PBM found gets a unique index. */ |
54 | int pci_num_controllers = 0; | 54 | int pci_num_pbms = 0; |
55 | 55 | ||
56 | volatile int pci_poke_in_progress; | 56 | volatile int pci_poke_in_progress; |
57 | volatile int pci_poke_cpu = -1; | 57 | volatile int pci_poke_cpu = -1; |
@@ -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) |
@@ -743,7 +743,6 @@ int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, | |||
743 | 743 | ||
744 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | 744 | struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) |
745 | { | 745 | { |
746 | struct pci_controller_info *p = pbm->parent; | ||
747 | struct device_node *node = pbm->prom_node; | 746 | struct device_node *node = pbm->prom_node; |
748 | struct pci_dev *host_pdev; | 747 | struct pci_dev *host_pdev; |
749 | struct pci_bus *bus; | 748 | struct pci_bus *bus; |
@@ -751,7 +750,7 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | |||
751 | printk("PCI: Scanning PBM %s\n", node->full_name); | 750 | printk("PCI: Scanning PBM %s\n", node->full_name); |
752 | 751 | ||
753 | /* XXX parent device? XXX */ | 752 | /* XXX parent device? XXX */ |
754 | bus = pci_create_bus(NULL, pbm->pci_first_busno, p->pci_ops, pbm); | 753 | bus = pci_create_bus(NULL, pbm->pci_first_busno, pbm->pci_ops, pbm); |
755 | if (!bus) { | 754 | if (!bus) { |
756 | printk(KERN_ERR "Failed to create bus for %s\n", | 755 | printk(KERN_ERR "Failed to create bus for %s\n", |
757 | node->full_name); | 756 | node->full_name); |
@@ -776,10 +775,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) | |||
776 | 775 | ||
777 | static void __init pci_scan_each_controller_bus(void) | 776 | static void __init pci_scan_each_controller_bus(void) |
778 | { | 777 | { |
779 | struct pci_controller_info *p; | 778 | struct pci_pbm_info *pbm; |
780 | 779 | ||
781 | for (p = pci_controller_root; p; p = p->next) | 780 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) |
782 | p->scan_bus(p); | 781 | pbm->scan_bus(pbm); |
783 | } | 782 | } |
784 | 783 | ||
785 | extern void power_init(void); | 784 | extern void power_init(void); |
@@ -787,7 +786,7 @@ extern void power_init(void); | |||
787 | static int __init pcibios_init(void) | 786 | static int __init pcibios_init(void) |
788 | { | 787 | { |
789 | pci_controller_probe(); | 788 | pci_controller_probe(); |
790 | if (pci_controller_root == NULL) | 789 | if (pci_pbm_root == NULL) |
791 | return 0; | 790 | return 0; |
792 | 791 | ||
793 | pci_scan_each_controller_bus(); | 792 | pci_scan_each_controller_bus(); |
@@ -922,10 +921,8 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc | |||
922 | enum pci_mmap_state mmap_state) | 921 | enum pci_mmap_state mmap_state) |
923 | { | 922 | { |
924 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 923 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; |
925 | struct pci_controller_info *p; | ||
926 | unsigned long space_size, user_offset, user_size; | 924 | unsigned long space_size, user_offset, user_size; |
927 | 925 | ||
928 | p = pbm->parent; | ||
929 | if (mmap_state == pci_mmap_io) { | 926 | if (mmap_state == pci_mmap_io) { |
930 | space_size = (pbm->io_space.end - | 927 | space_size = (pbm->io_space.end - |
931 | pbm->io_space.start) + 1; | 928 | pbm->io_space.start) + 1; |
@@ -1078,11 +1075,7 @@ int pci_domain_nr(struct pci_bus *pbus) | |||
1078 | if (pbm == NULL || pbm->parent == NULL) { | 1075 | if (pbm == NULL || pbm->parent == NULL) { |
1079 | ret = -ENXIO; | 1076 | ret = -ENXIO; |
1080 | } else { | 1077 | } else { |
1081 | struct pci_controller_info *p = pbm->parent; | 1078 | ret = pbm->index; |
1082 | |||
1083 | ret = p->index; | ||
1084 | ret = ((ret << 1) + | ||
1085 | ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); | ||
1086 | } | 1079 | } |
1087 | 1080 | ||
1088 | return ret; | 1081 | return ret; |
@@ -1093,17 +1086,12 @@ EXPORT_SYMBOL(pci_domain_nr); | |||
1093 | int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) | 1086 | int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) |
1094 | { | 1087 | { |
1095 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 1088 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; |
1096 | struct pci_controller_info *p = pbm->parent; | 1089 | int virt_irq; |
1097 | int virt_irq, err; | ||
1098 | 1090 | ||
1099 | if (!pbm->msi_num || !p->setup_msi_irq) | 1091 | if (!pbm->setup_msi_irq) |
1100 | return -EINVAL; | 1092 | return -EINVAL; |
1101 | 1093 | ||
1102 | err = p->setup_msi_irq(&virt_irq, pdev, desc); | 1094 | return pbm->setup_msi_irq(&virt_irq, pdev, desc); |
1103 | if (err) | ||
1104 | return err; | ||
1105 | |||
1106 | return 0; | ||
1107 | } | 1095 | } |
1108 | 1096 | ||
1109 | void arch_teardown_msi_irq(unsigned int virt_irq) | 1097 | void arch_teardown_msi_irq(unsigned int virt_irq) |
@@ -1111,12 +1099,11 @@ void arch_teardown_msi_irq(unsigned int virt_irq) | |||
1111 | struct msi_desc *entry = get_irq_msi(virt_irq); | 1099 | struct msi_desc *entry = get_irq_msi(virt_irq); |
1112 | struct pci_dev *pdev = entry->dev; | 1100 | struct pci_dev *pdev = entry->dev; |
1113 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 1101 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; |
1114 | struct pci_controller_info *p = pbm->parent; | ||
1115 | 1102 | ||
1116 | if (!pbm->msi_num || !p->setup_msi_irq) | 1103 | if (!pbm->teardown_msi_irq) |
1117 | return; | 1104 | return; |
1118 | 1105 | ||
1119 | return p->teardown_msi_irq(virt_irq, pdev); | 1106 | return pbm->teardown_msi_irq(virt_irq, pdev); |
1120 | } | 1107 | } |
1121 | #endif /* !(CONFIG_PCI_MSI) */ | 1108 | #endif /* !(CONFIG_PCI_MSI) */ |
1122 | 1109 | ||
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 1e6aeedf43c4..76faaa8135dd 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c | |||
@@ -9,12 +9,26 @@ | |||
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | 11 | ||
12 | #include <asm/pbm.h> | ||
13 | #include <asm/prom.h> | 12 | #include <asm/prom.h> |
14 | #include <asm/of_device.h> | 13 | #include <asm/of_device.h> |
14 | #include <asm/oplib.h> | ||
15 | 15 | ||
16 | #include "pci_impl.h" | 16 | #include "pci_impl.h" |
17 | 17 | ||
18 | void pci_get_pbm_props(struct pci_pbm_info *pbm) | ||
19 | { | ||
20 | const u32 *val = of_get_property(pbm->prom_node, "bus-range", NULL); | ||
21 | |||
22 | pbm->pci_first_busno = val[0]; | ||
23 | pbm->pci_last_busno = val[1]; | ||
24 | |||
25 | val = of_get_property(pbm->prom_node, "ino-bitmap", NULL); | ||
26 | if (val) { | ||
27 | pbm->ino_bitmap = (((u64)val[1] << 32UL) | | ||
28 | ((u64)val[0] << 0UL)); | ||
29 | } | ||
30 | } | ||
31 | |||
18 | static void pci_register_legacy_regions(struct resource *io_res, | 32 | static void pci_register_legacy_regions(struct resource *io_res, |
19 | struct resource *mem_res) | 33 | struct resource *mem_res) |
20 | { | 34 | { |
@@ -149,8 +163,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
149 | } | 163 | } |
150 | 164 | ||
151 | /* Generic helper routines for PCI error reporting. */ | 165 | /* Generic helper routines for PCI error reporting. */ |
152 | void pci_scan_for_target_abort(struct pci_controller_info *p, | 166 | void pci_scan_for_target_abort(struct pci_pbm_info *pbm, |
153 | struct pci_pbm_info *pbm, | ||
154 | struct pci_bus *pbus) | 167 | struct pci_bus *pbus) |
155 | { | 168 | { |
156 | struct pci_dev *pdev; | 169 | struct pci_dev *pdev; |
@@ -165,18 +178,16 @@ void pci_scan_for_target_abort(struct pci_controller_info *p, | |||
165 | PCI_STATUS_REC_TARGET_ABORT)); | 178 | PCI_STATUS_REC_TARGET_ABORT)); |
166 | if (error_bits) { | 179 | if (error_bits) { |
167 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | 180 | pci_write_config_word(pdev, PCI_STATUS, error_bits); |
168 | printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n", | 181 | printk("%s: Device %s saw Target Abort [%016x]\n", |
169 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | 182 | pbm->name, pci_name(pdev), status); |
170 | pci_name(pdev), status); | ||
171 | } | 183 | } |
172 | } | 184 | } |
173 | 185 | ||
174 | list_for_each_entry(bus, &pbus->children, node) | 186 | list_for_each_entry(bus, &pbus->children, node) |
175 | pci_scan_for_target_abort(p, pbm, bus); | 187 | pci_scan_for_target_abort(pbm, bus); |
176 | } | 188 | } |
177 | 189 | ||
178 | void pci_scan_for_master_abort(struct pci_controller_info *p, | 190 | void pci_scan_for_master_abort(struct pci_pbm_info *pbm, |
179 | struct pci_pbm_info *pbm, | ||
180 | struct pci_bus *pbus) | 191 | struct pci_bus *pbus) |
181 | { | 192 | { |
182 | struct pci_dev *pdev; | 193 | struct pci_dev *pdev; |
@@ -190,18 +201,16 @@ void pci_scan_for_master_abort(struct pci_controller_info *p, | |||
190 | (status & (PCI_STATUS_REC_MASTER_ABORT)); | 201 | (status & (PCI_STATUS_REC_MASTER_ABORT)); |
191 | if (error_bits) { | 202 | if (error_bits) { |
192 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | 203 | pci_write_config_word(pdev, PCI_STATUS, error_bits); |
193 | printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n", | 204 | printk("%s: Device %s received Master Abort [%016x]\n", |
194 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | 205 | pbm->name, pci_name(pdev), status); |
195 | pci_name(pdev), status); | ||
196 | } | 206 | } |
197 | } | 207 | } |
198 | 208 | ||
199 | list_for_each_entry(bus, &pbus->children, node) | 209 | list_for_each_entry(bus, &pbus->children, node) |
200 | pci_scan_for_master_abort(p, pbm, bus); | 210 | pci_scan_for_master_abort(pbm, bus); |
201 | } | 211 | } |
202 | 212 | ||
203 | void pci_scan_for_parity_error(struct pci_controller_info *p, | 213 | void pci_scan_for_parity_error(struct pci_pbm_info *pbm, |
204 | struct pci_pbm_info *pbm, | ||
205 | struct pci_bus *pbus) | 214 | struct pci_bus *pbus) |
206 | { | 215 | { |
207 | struct pci_dev *pdev; | 216 | struct pci_dev *pdev; |
@@ -216,12 +225,11 @@ void pci_scan_for_parity_error(struct pci_controller_info *p, | |||
216 | PCI_STATUS_DETECTED_PARITY)); | 225 | PCI_STATUS_DETECTED_PARITY)); |
217 | if (error_bits) { | 226 | if (error_bits) { |
218 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | 227 | pci_write_config_word(pdev, PCI_STATUS, error_bits); |
219 | printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n", | 228 | printk("%s: Device %s saw Parity Error [%016x]\n", |
220 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | 229 | pbm->name, pci_name(pdev), status); |
221 | pci_name(pdev), status); | ||
222 | } | 230 | } |
223 | } | 231 | } |
224 | 232 | ||
225 | list_for_each_entry(bus, &pbus->children, node) | 233 | list_for_each_entry(bus, &pbus->children, node) |
226 | pci_scan_for_parity_error(p, pbm, bus); | 234 | pci_scan_for_parity_error(pbm, bus); |
227 | } | 235 | } |
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 0fe626631e12..2e0eb4ee8f71 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | 9 | ||
10 | #include <asm/pbm.h> | ||
11 | #include <asm/oplib.h> | 10 | #include <asm/oplib.h> |
12 | #include <asm/prom.h> | 11 | #include <asm/prom.h> |
13 | 12 | ||
@@ -160,21 +159,9 @@ static struct pci_ops pci_fire_ops = { | |||
160 | .write = fire_write_pci_cfg, | 159 | .write = fire_write_pci_cfg, |
161 | }; | 160 | }; |
162 | 161 | ||
163 | static void pbm_scan_bus(struct pci_controller_info *p, | 162 | static void pci_fire_scan_bus(struct pci_pbm_info *pbm) |
164 | struct pci_pbm_info *pbm) | ||
165 | { | 163 | { |
166 | pbm->pci_bus = pci_scan_one_pbm(pbm); | 164 | 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 | 165 | ||
179 | /* XXX register error interrupt handlers XXX */ | 166 | /* XXX register error interrupt handlers XXX */ |
180 | } | 167 | } |
@@ -313,18 +300,24 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) | |||
313 | } | 300 | } |
314 | 301 | ||
315 | static void pci_fire_pbm_init(struct pci_controller_info *p, | 302 | static void pci_fire_pbm_init(struct pci_controller_info *p, |
316 | struct device_node *dp, u32 portid) | 303 | struct device_node *dp, u32 portid) |
317 | { | 304 | { |
318 | const struct linux_prom64_registers *regs; | 305 | const struct linux_prom64_registers *regs; |
319 | struct pci_pbm_info *pbm; | 306 | struct pci_pbm_info *pbm; |
320 | const u32 *ino_bitmap; | ||
321 | const unsigned int *busrange; | ||
322 | 307 | ||
323 | if ((portid & 1) == 0) | 308 | if ((portid & 1) == 0) |
324 | pbm = &p->pbm_A; | 309 | pbm = &p->pbm_A; |
325 | else | 310 | else |
326 | pbm = &p->pbm_B; | 311 | pbm = &p->pbm_B; |
327 | 312 | ||
313 | pbm->next = pci_pbm_root; | ||
314 | pci_pbm_root = pbm; | ||
315 | |||
316 | pbm->scan_bus = pci_fire_scan_bus; | ||
317 | pbm->pci_ops = &pci_fire_ops; | ||
318 | |||
319 | pbm->index = pci_num_pbms++; | ||
320 | |||
328 | pbm->portid = portid; | 321 | pbm->portid = portid; |
329 | pbm->parent = p; | 322 | pbm->parent = p; |
330 | pbm->prom_node = dp; | 323 | pbm->prom_node = dp; |
@@ -338,13 +331,7 @@ static void pci_fire_pbm_init(struct pci_controller_info *p, | |||
338 | 331 | ||
339 | pci_determine_mem_io_space(pbm); | 332 | pci_determine_mem_io_space(pbm); |
340 | 333 | ||
341 | ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); | 334 | pci_get_pbm_props(pbm); |
342 | pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | | ||
343 | ((u64)ino_bitmap[0] << 0UL)); | ||
344 | |||
345 | busrange = of_get_property(dp, "bus-range", NULL); | ||
346 | pbm->pci_first_busno = busrange[0]; | ||
347 | pbm->pci_last_busno = busrange[1]; | ||
348 | 335 | ||
349 | pci_fire_hw_init(pbm); | 336 | pci_fire_hw_init(pbm); |
350 | pci_fire_pbm_iommu_init(pbm); | 337 | pci_fire_pbm_iommu_init(pbm); |
@@ -362,19 +349,11 @@ void fire_pci_init(struct device_node *dp, const char *model_name) | |||
362 | struct pci_controller_info *p; | 349 | struct pci_controller_info *p; |
363 | u32 portid = of_getintprop_default(dp, "portid", 0xff); | 350 | u32 portid = of_getintprop_default(dp, "portid", 0xff); |
364 | struct iommu *iommu; | 351 | struct iommu *iommu; |
352 | struct pci_pbm_info *pbm; | ||
365 | 353 | ||
366 | for (p = pci_controller_root; p; p = p->next) { | 354 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
367 | struct pci_pbm_info *pbm; | ||
368 | |||
369 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
370 | continue; | ||
371 | |||
372 | pbm = (p->pbm_A.prom_node ? | ||
373 | &p->pbm_A : | ||
374 | &p->pbm_B); | ||
375 | |||
376 | if (portid_compare(pbm->portid, portid)) { | 355 | if (portid_compare(pbm->portid, portid)) { |
377 | pci_fire_pbm_init(p, dp, portid); | 356 | pci_fire_pbm_init(pbm->parent, dp, portid); |
378 | return; | 357 | return; |
379 | } | 358 | } |
380 | } | 359 | } |
@@ -395,14 +374,7 @@ void fire_pci_init(struct device_node *dp, const char *model_name) | |||
395 | 374 | ||
396 | p->pbm_B.iommu = iommu; | 375 | p->pbm_B.iommu = iommu; |
397 | 376 | ||
398 | p->next = pci_controller_root; | ||
399 | pci_controller_root = p; | ||
400 | |||
401 | p->index = pci_num_controllers++; | ||
402 | |||
403 | p->scan_bus = pci_fire_scan_bus; | ||
404 | /* XXX MSI support XXX */ | 377 | /* XXX MSI support XXX */ |
405 | p->pci_ops = &pci_fire_ops; | ||
406 | 378 | ||
407 | /* Like PSYCHO and SCHIZO we have a 2GB aligned area | 379 | /* Like PSYCHO and SCHIZO we have a 2GB aligned area |
408 | * for memory space. | 380 | * for memory space. |
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 1208583fcb83..8e38023868aa 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h | |||
@@ -8,15 +8,129 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/spinlock.h> | 10 | #include <linux/spinlock.h> |
11 | #include <linux/pci.h> | ||
12 | #include <linux/msi.h> | ||
11 | #include <asm/io.h> | 13 | #include <asm/io.h> |
12 | #include <asm/prom.h> | 14 | #include <asm/prom.h> |
15 | #include <asm/iommu.h> | ||
13 | 16 | ||
14 | extern struct pci_controller_info *pci_controller_root; | 17 | /* The abstraction used here is that there are PCI controllers, |
18 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules | ||
19 | * underneath. Each PCI bus module uses an IOMMU (shared by both | ||
20 | * PBMs of a controller, or per-PBM), and if a streaming buffer | ||
21 | * is present, each PCI bus module has it's own. (ie. the IOMMU | ||
22 | * might be shared between PBMs, the STC is never shared) | ||
23 | * Furthermore, each PCI bus module controls it's own autonomous | ||
24 | * PCI bus. | ||
25 | */ | ||
26 | |||
27 | #define PCI_STC_FLUSHFLAG_INIT(STC) \ | ||
28 | (*((STC)->strbuf_flushflag) = 0UL) | ||
29 | #define PCI_STC_FLUSHFLAG_SET(STC) \ | ||
30 | (*((STC)->strbuf_flushflag) != 0UL) | ||
31 | |||
32 | struct pci_controller_info; | ||
33 | |||
34 | struct pci_pbm_info { | ||
35 | struct pci_pbm_info *next; | ||
36 | int index; | ||
37 | |||
38 | /* PCI controller we sit under. */ | ||
39 | struct pci_controller_info *parent; | ||
40 | |||
41 | /* Physical address base of controller registers. */ | ||
42 | unsigned long controller_regs; | ||
43 | |||
44 | /* Physical address base of PBM registers. */ | ||
45 | unsigned long pbm_regs; | ||
46 | |||
47 | /* Physical address of DMA sync register, if any. */ | ||
48 | unsigned long sync_reg; | ||
49 | |||
50 | /* Opaque 32-bit system bus Port ID. */ | ||
51 | u32 portid; | ||
52 | |||
53 | /* Opaque 32-bit handle used for hypervisor calls. */ | ||
54 | u32 devhandle; | ||
55 | |||
56 | /* Chipset version information. */ | ||
57 | int chip_type; | ||
58 | #define PBM_CHIP_TYPE_SABRE 1 | ||
59 | #define PBM_CHIP_TYPE_PSYCHO 2 | ||
60 | #define PBM_CHIP_TYPE_SCHIZO 3 | ||
61 | #define PBM_CHIP_TYPE_SCHIZO_PLUS 4 | ||
62 | #define PBM_CHIP_TYPE_TOMATILLO 5 | ||
63 | int chip_version; | ||
64 | int chip_revision; | ||
65 | |||
66 | /* Name used for top-level resources. */ | ||
67 | char *name; | ||
68 | |||
69 | /* OBP specific information. */ | ||
70 | struct device_node *prom_node; | ||
71 | u64 ino_bitmap; | ||
72 | |||
73 | /* PBM I/O and Memory space resources. */ | ||
74 | struct resource io_space; | ||
75 | struct resource mem_space; | ||
76 | |||
77 | /* Base of PCI Config space, can be per-PBM or shared. */ | ||
78 | unsigned long config_space; | ||
79 | |||
80 | /* State of 66MHz capabilities on this PBM. */ | ||
81 | int is_66mhz_capable; | ||
82 | int all_devs_66mhz; | ||
83 | |||
84 | #ifdef CONFIG_PCI_MSI | ||
85 | /* MSI info. */ | ||
86 | u32 msiq_num; | ||
87 | u32 msiq_ent_count; | ||
88 | u32 msiq_first; | ||
89 | u32 msiq_first_devino; | ||
90 | u32 msi_num; | ||
91 | u32 msi_first; | ||
92 | u32 msi_data_mask; | ||
93 | u32 msix_data_width; | ||
94 | u64 msi32_start; | ||
95 | u64 msi64_start; | ||
96 | u32 msi32_len; | ||
97 | u32 msi64_len; | ||
98 | void *msi_queues; | ||
99 | unsigned long *msi_bitmap; | ||
100 | int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, | ||
101 | struct msi_desc *entry); | ||
102 | void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev); | ||
103 | #endif /* !(CONFIG_PCI_MSI) */ | ||
104 | |||
105 | /* This PBM's streaming buffer. */ | ||
106 | struct strbuf stc; | ||
107 | |||
108 | /* IOMMU state, potentially shared by both PBM segments. */ | ||
109 | struct iommu *iommu; | ||
110 | |||
111 | /* Now things for the actual PCI bus probes. */ | ||
112 | unsigned int pci_first_busno; | ||
113 | unsigned int pci_last_busno; | ||
114 | struct pci_bus *pci_bus; | ||
115 | void (*scan_bus)(struct pci_pbm_info *); | ||
116 | struct pci_ops *pci_ops; | ||
117 | }; | ||
118 | |||
119 | struct pci_controller_info { | ||
120 | /* The PCI bus modules controlled by us. */ | ||
121 | struct pci_pbm_info pbm_A; | ||
122 | struct pci_pbm_info pbm_B; | ||
123 | }; | ||
124 | |||
125 | extern struct pci_pbm_info *pci_pbm_root; | ||
15 | extern unsigned long pci_memspace_mask; | 126 | extern unsigned long pci_memspace_mask; |
16 | 127 | ||
17 | extern int pci_num_controllers; | 128 | extern int pci_num_pbms; |
18 | 129 | ||
19 | /* PCI bus scanning and fixup support. */ | 130 | /* PCI bus scanning and fixup support. */ |
131 | extern void pci_iommu_table_init(struct iommu *iommu, int tsbsize, | ||
132 | u32 dma_offset, u32 dma_addr_mask); | ||
133 | extern void pci_get_pbm_props(struct pci_pbm_info *pbm); | ||
20 | extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); | 134 | extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); |
21 | extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); | 135 | extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); |
22 | 136 | ||
@@ -30,9 +144,9 @@ extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, | |||
30 | u32 value); | 144 | u32 value); |
31 | 145 | ||
32 | /* Error reporting support. */ | 146 | /* Error reporting support. */ |
33 | extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); | 147 | extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); |
34 | extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); | 148 | extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); |
35 | extern void pci_scan_for_parity_error(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); | 149 | extern void pci_scan_for_parity_error(struct pci_pbm_info *, struct pci_bus *); |
36 | 150 | ||
37 | /* Configuration space access. */ | 151 | /* Configuration space access. */ |
38 | extern void pci_config_read8(u8 *addr, u8 *ret); | 152 | extern void pci_config_read8(u8 *addr, u8 *ret); |
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 9e405cbbcb0d..dfd6f9f4790b 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c | |||
@@ -8,10 +8,12 @@ | |||
8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/pci.h> | ||
11 | 12 | ||
12 | #include <asm/pbm.h> | 13 | #include <asm/oplib.h> |
13 | 14 | ||
14 | #include "iommu_common.h" | 15 | #include "iommu_common.h" |
16 | #include "pci_impl.h" | ||
15 | 17 | ||
16 | #define PCI_STC_CTXMATCH_ADDR(STC, CTX) \ | 18 | #define PCI_STC_CTXMATCH_ADDR(STC, CTX) \ |
17 | ((STC)->strbuf_ctxmatch_base + ((CTX) << 3)) | 19 | ((STC)->strbuf_ctxmatch_base + ((CTX) << 3)) |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 253d40ec2245..2edcb1dd13c3 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -12,12 +12,12 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | 14 | ||
15 | #include <asm/pbm.h> | ||
16 | #include <asm/iommu.h> | 15 | #include <asm/iommu.h> |
17 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
18 | #include <asm/starfire.h> | 17 | #include <asm/starfire.h> |
19 | #include <asm/prom.h> | 18 | #include <asm/prom.h> |
20 | #include <asm/of_device.h> | 19 | #include <asm/of_device.h> |
20 | #include <asm/oplib.h> | ||
21 | 21 | ||
22 | #include "pci_impl.h" | 22 | #include "pci_impl.h" |
23 | #include "iommu_common.h" | 23 | #include "iommu_common.h" |
@@ -98,13 +98,8 @@ static int psycho_out_of_range(struct pci_pbm_info *pbm, | |||
98 | unsigned char bus, | 98 | unsigned char bus, |
99 | unsigned char devfn) | 99 | unsigned char devfn) |
100 | { | 100 | { |
101 | return ((pbm->parent == 0) || | 101 | return ((bus == pbm->pci_first_busno) && |
102 | ((pbm == &pbm->parent->pbm_B) && | 102 | PCI_SLOT(devfn) > 8); |
103 | (bus == pbm->pci_first_busno) && | ||
104 | PCI_SLOT(devfn) > 8) || | ||
105 | ((pbm == &pbm->parent->pbm_A) && | ||
106 | (bus == pbm->pci_first_busno) && | ||
107 | PCI_SLOT(devfn) > 8)); | ||
108 | } | 103 | } |
109 | 104 | ||
110 | /* PSYCHO PCI configuration space accessors. */ | 105 | /* PSYCHO PCI configuration space accessors. */ |
@@ -265,12 +260,11 @@ static unsigned long stc_error_buf[128]; | |||
265 | static unsigned long stc_tag_buf[16]; | 260 | static unsigned long stc_tag_buf[16]; |
266 | static unsigned long stc_line_buf[16]; | 261 | static unsigned long stc_line_buf[16]; |
267 | 262 | ||
268 | static void __psycho_check_one_stc(struct pci_controller_info *p, | 263 | static void __psycho_check_one_stc(struct pci_pbm_info *pbm, |
269 | struct pci_pbm_info *pbm, | ||
270 | int is_pbm_a) | 264 | int is_pbm_a) |
271 | { | 265 | { |
272 | struct strbuf *strbuf = &pbm->stc; | 266 | struct strbuf *strbuf = &pbm->stc; |
273 | unsigned long regbase = p->pbm_A.controller_regs; | 267 | unsigned long regbase = pbm->controller_regs; |
274 | unsigned long err_base, tag_base, line_base; | 268 | unsigned long err_base, tag_base, line_base; |
275 | u64 control; | 269 | u64 control; |
276 | int i; | 270 | int i; |
@@ -326,9 +320,8 @@ static void __psycho_check_one_stc(struct pci_controller_info *p, | |||
326 | unsigned long errval = stc_error_buf[j]; | 320 | unsigned long errval = stc_error_buf[j]; |
327 | if (errval != 0) { | 321 | if (errval != 0) { |
328 | saw_error++; | 322 | saw_error++; |
329 | printk("PSYCHO%d(PBM%c): STC_ERR(%d)[wr(%d)rd(%d)]\n", | 323 | printk("%s: STC_ERR(%d)[wr(%d)rd(%d)]\n", |
330 | p->index, | 324 | pbm->name, |
331 | (is_pbm_a ? 'A' : 'B'), | ||
332 | j, | 325 | j, |
333 | (errval & PSYCHO_STCERR_WRITE) ? 1 : 0, | 326 | (errval & PSYCHO_STCERR_WRITE) ? 1 : 0, |
334 | (errval & PSYCHO_STCERR_READ) ? 1 : 0); | 327 | (errval & PSYCHO_STCERR_READ) ? 1 : 0); |
@@ -337,18 +330,16 @@ static void __psycho_check_one_stc(struct pci_controller_info *p, | |||
337 | if (saw_error != 0) { | 330 | if (saw_error != 0) { |
338 | unsigned long tagval = stc_tag_buf[i]; | 331 | unsigned long tagval = stc_tag_buf[i]; |
339 | unsigned long lineval = stc_line_buf[i]; | 332 | unsigned long lineval = stc_line_buf[i]; |
340 | printk("PSYCHO%d(PBM%c): STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)W(%d)]\n", | 333 | printk("%s: STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)W(%d)]\n", |
341 | p->index, | 334 | pbm->name, |
342 | (is_pbm_a ? 'A' : 'B'), | ||
343 | i, | 335 | i, |
344 | ((tagval & PSYCHO_STCTAG_PPN) >> 19UL), | 336 | ((tagval & PSYCHO_STCTAG_PPN) >> 19UL), |
345 | (tagval & PSYCHO_STCTAG_VPN), | 337 | (tagval & PSYCHO_STCTAG_VPN), |
346 | ((tagval & PSYCHO_STCTAG_VALID) ? 1 : 0), | 338 | ((tagval & PSYCHO_STCTAG_VALID) ? 1 : 0), |
347 | ((tagval & PSYCHO_STCTAG_WRITE) ? 1 : 0)); | 339 | ((tagval & PSYCHO_STCTAG_WRITE) ? 1 : 0)); |
348 | printk("PSYCHO%d(PBM%c): STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" | 340 | printk("%s: STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" |
349 | "V(%d)FOFN(%d)]\n", | 341 | "V(%d)FOFN(%d)]\n", |
350 | p->index, | 342 | pbm->name, |
351 | (is_pbm_a ? 'A' : 'B'), | ||
352 | i, | 343 | i, |
353 | ((lineval & PSYCHO_STCLINE_LINDX) >> 21UL), | 344 | ((lineval & PSYCHO_STCLINE_LINDX) >> 21UL), |
354 | ((lineval & PSYCHO_STCLINE_SPTR) >> 15UL), | 345 | ((lineval & PSYCHO_STCLINE_SPTR) >> 15UL), |
@@ -362,20 +353,13 @@ static void __psycho_check_one_stc(struct pci_controller_info *p, | |||
362 | spin_unlock(&stc_buf_lock); | 353 | spin_unlock(&stc_buf_lock); |
363 | } | 354 | } |
364 | 355 | ||
365 | static void __psycho_check_stc_error(struct pci_controller_info *p, | 356 | static void __psycho_check_stc_error(struct pci_pbm_info *pbm, |
366 | unsigned long afsr, | 357 | unsigned long afsr, |
367 | unsigned long afar, | 358 | unsigned long afar, |
368 | enum psycho_error_type type) | 359 | enum psycho_error_type type) |
369 | { | 360 | { |
370 | struct pci_pbm_info *pbm; | 361 | __psycho_check_one_stc(pbm, |
371 | 362 | (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 | } | 363 | } |
380 | 364 | ||
381 | /* When an Uncorrectable Error or a PCI Error happens, we | 365 | /* When an Uncorrectable Error or a PCI Error happens, we |
@@ -413,12 +397,12 @@ static void __psycho_check_stc_error(struct pci_controller_info *p, | |||
413 | #define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL) | 397 | #define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL) |
414 | #define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL) | 398 | #define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL) |
415 | #define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL | 399 | #define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL |
416 | static void psycho_check_iommu_error(struct pci_controller_info *p, | 400 | static void psycho_check_iommu_error(struct pci_pbm_info *pbm, |
417 | unsigned long afsr, | 401 | unsigned long afsr, |
418 | unsigned long afar, | 402 | unsigned long afar, |
419 | enum psycho_error_type type) | 403 | enum psycho_error_type type) |
420 | { | 404 | { |
421 | struct iommu *iommu = p->pbm_A.iommu; | 405 | struct iommu *iommu = pbm->iommu; |
422 | unsigned long iommu_tag[16]; | 406 | unsigned long iommu_tag[16]; |
423 | unsigned long iommu_data[16]; | 407 | unsigned long iommu_data[16]; |
424 | unsigned long flags; | 408 | unsigned long flags; |
@@ -449,8 +433,8 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
449 | type_string = "ECC Error"; | 433 | type_string = "ECC Error"; |
450 | break; | 434 | break; |
451 | }; | 435 | }; |
452 | printk("PSYCHO%d: IOMMU Error, type[%s]\n", | 436 | printk("%s: IOMMU Error, type[%s]\n", |
453 | p->index, type_string); | 437 | pbm->name, type_string); |
454 | 438 | ||
455 | /* Put the IOMMU into diagnostic mode and probe | 439 | /* Put the IOMMU into diagnostic mode and probe |
456 | * it's TLB for entries with error status. | 440 | * it's TLB for entries with error status. |
@@ -465,7 +449,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
465 | psycho_write(iommu->iommu_control, | 449 | psycho_write(iommu->iommu_control, |
466 | control | PSYCHO_IOMMU_CTRL_DENAB); | 450 | control | PSYCHO_IOMMU_CTRL_DENAB); |
467 | for (i = 0; i < 16; i++) { | 451 | for (i = 0; i < 16; i++) { |
468 | unsigned long base = p->pbm_A.controller_regs; | 452 | unsigned long base = pbm->controller_regs; |
469 | 453 | ||
470 | iommu_tag[i] = | 454 | iommu_tag[i] = |
471 | psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); | 455 | psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); |
@@ -503,20 +487,20 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
503 | type_string = "ECC Error"; | 487 | type_string = "ECC Error"; |
504 | break; | 488 | break; |
505 | }; | 489 | }; |
506 | printk("PSYCHO%d: IOMMU TAG(%d)[error(%s) wr(%d) str(%d) sz(%dK) vpg(%08lx)]\n", | 490 | printk("%s: IOMMU TAG(%d)[error(%s) wr(%d) str(%d) sz(%dK) vpg(%08lx)]\n", |
507 | p->index, i, type_string, | 491 | pbm->name, i, type_string, |
508 | ((tag & PSYCHO_IOMMU_TAG_WRITE) ? 1 : 0), | 492 | ((tag & PSYCHO_IOMMU_TAG_WRITE) ? 1 : 0), |
509 | ((tag & PSYCHO_IOMMU_TAG_STREAM) ? 1 : 0), | 493 | ((tag & PSYCHO_IOMMU_TAG_STREAM) ? 1 : 0), |
510 | ((tag & PSYCHO_IOMMU_TAG_SIZE) ? 64 : 8), | 494 | ((tag & PSYCHO_IOMMU_TAG_SIZE) ? 64 : 8), |
511 | (tag & PSYCHO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT); | 495 | (tag & PSYCHO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT); |
512 | printk("PSYCHO%d: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", | 496 | printk("%s: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", |
513 | p->index, i, | 497 | pbm->name, i, |
514 | ((data & PSYCHO_IOMMU_DATA_VALID) ? 1 : 0), | 498 | ((data & PSYCHO_IOMMU_DATA_VALID) ? 1 : 0), |
515 | ((data & PSYCHO_IOMMU_DATA_CACHE) ? 1 : 0), | 499 | ((data & PSYCHO_IOMMU_DATA_CACHE) ? 1 : 0), |
516 | (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); | 500 | (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); |
517 | } | 501 | } |
518 | } | 502 | } |
519 | __psycho_check_stc_error(p, afsr, afar, type); | 503 | __psycho_check_stc_error(pbm, afsr, afar, type); |
520 | spin_unlock_irqrestore(&iommu->lock, flags); | 504 | spin_unlock_irqrestore(&iommu->lock, flags); |
521 | } | 505 | } |
522 | 506 | ||
@@ -541,9 +525,10 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, | |||
541 | 525 | ||
542 | static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | 526 | static irqreturn_t psycho_ue_intr(int irq, void *dev_id) |
543 | { | 527 | { |
544 | struct pci_controller_info *p = dev_id; | 528 | struct pci_pbm_info *pbm = dev_id; |
545 | unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR; | 529 | struct pci_controller_info *p = pbm->parent; |
546 | unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFAR; | 530 | unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; |
531 | unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; | ||
547 | unsigned long afsr, afar, error_bits; | 532 | unsigned long afsr, afar, error_bits; |
548 | int reported; | 533 | int reported; |
549 | 534 | ||
@@ -560,22 +545,22 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | |||
560 | psycho_write(afsr_reg, error_bits); | 545 | psycho_write(afsr_reg, error_bits); |
561 | 546 | ||
562 | /* Log the error. */ | 547 | /* Log the error. */ |
563 | printk("PSYCHO%d: Uncorrectable Error, primary error type[%s]\n", | 548 | printk("%s: Uncorrectable Error, primary error type[%s]\n", |
564 | p->index, | 549 | pbm->name, |
565 | (((error_bits & PSYCHO_UEAFSR_PPIO) ? | 550 | (((error_bits & PSYCHO_UEAFSR_PPIO) ? |
566 | "PIO" : | 551 | "PIO" : |
567 | ((error_bits & PSYCHO_UEAFSR_PDRD) ? | 552 | ((error_bits & PSYCHO_UEAFSR_PDRD) ? |
568 | "DMA Read" : | 553 | "DMA Read" : |
569 | ((error_bits & PSYCHO_UEAFSR_PDWR) ? | 554 | ((error_bits & PSYCHO_UEAFSR_PDWR) ? |
570 | "DMA Write" : "???"))))); | 555 | "DMA Write" : "???"))))); |
571 | printk("PSYCHO%d: bytemask[%04lx] dword_offset[%lx] UPA_MID[%02lx] was_block(%d)\n", | 556 | printk("%s: bytemask[%04lx] dword_offset[%lx] UPA_MID[%02lx] was_block(%d)\n", |
572 | p->index, | 557 | pbm->name, |
573 | (afsr & PSYCHO_UEAFSR_BMSK) >> 32UL, | 558 | (afsr & PSYCHO_UEAFSR_BMSK) >> 32UL, |
574 | (afsr & PSYCHO_UEAFSR_DOFF) >> 29UL, | 559 | (afsr & PSYCHO_UEAFSR_DOFF) >> 29UL, |
575 | (afsr & PSYCHO_UEAFSR_MID) >> 24UL, | 560 | (afsr & PSYCHO_UEAFSR_MID) >> 24UL, |
576 | ((afsr & PSYCHO_UEAFSR_BLK) ? 1 : 0)); | 561 | ((afsr & PSYCHO_UEAFSR_BLK) ? 1 : 0)); |
577 | printk("PSYCHO%d: UE AFAR [%016lx]\n", p->index, afar); | 562 | printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); |
578 | printk("PSYCHO%d: UE Secondary errors [", p->index); | 563 | printk("%s: UE Secondary errors [", pbm->name); |
579 | reported = 0; | 564 | reported = 0; |
580 | if (afsr & PSYCHO_UEAFSR_SPIO) { | 565 | if (afsr & PSYCHO_UEAFSR_SPIO) { |
581 | reported++; | 566 | reported++; |
@@ -593,8 +578,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | |||
593 | printk("(none)"); | 578 | printk("(none)"); |
594 | printk("]\n"); | 579 | printk("]\n"); |
595 | 580 | ||
596 | /* Interrogate IOMMU for error status. */ | 581 | /* Interrogate both IOMMUs for error status. */ |
597 | psycho_check_iommu_error(p, afsr, afar, UE_ERR); | 582 | psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR); |
583 | psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR); | ||
598 | 584 | ||
599 | return IRQ_HANDLED; | 585 | return IRQ_HANDLED; |
600 | } | 586 | } |
@@ -618,9 +604,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) | |||
618 | 604 | ||
619 | static irqreturn_t psycho_ce_intr(int irq, void *dev_id) | 605 | static irqreturn_t psycho_ce_intr(int irq, void *dev_id) |
620 | { | 606 | { |
621 | struct pci_controller_info *p = dev_id; | 607 | struct pci_pbm_info *pbm = dev_id; |
622 | unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR; | 608 | unsigned long afsr_reg = pbm->controller_regs + PSYCHO_CE_AFSR; |
623 | unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFAR; | 609 | unsigned long afar_reg = pbm->controller_regs + PSYCHO_CE_AFAR; |
624 | unsigned long afsr, afar, error_bits; | 610 | unsigned long afsr, afar, error_bits; |
625 | int reported; | 611 | int reported; |
626 | 612 | ||
@@ -637,8 +623,8 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) | |||
637 | psycho_write(afsr_reg, error_bits); | 623 | psycho_write(afsr_reg, error_bits); |
638 | 624 | ||
639 | /* Log the error. */ | 625 | /* Log the error. */ |
640 | printk("PSYCHO%d: Correctable Error, primary error type[%s]\n", | 626 | printk("%s: Correctable Error, primary error type[%s]\n", |
641 | p->index, | 627 | pbm->name, |
642 | (((error_bits & PSYCHO_CEAFSR_PPIO) ? | 628 | (((error_bits & PSYCHO_CEAFSR_PPIO) ? |
643 | "PIO" : | 629 | "PIO" : |
644 | ((error_bits & PSYCHO_CEAFSR_PDRD) ? | 630 | ((error_bits & PSYCHO_CEAFSR_PDRD) ? |
@@ -649,16 +635,16 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) | |||
649 | /* XXX Use syndrome and afar to print out module string just like | 635 | /* XXX Use syndrome and afar to print out module string just like |
650 | * XXX UDB CE trap handler does... -DaveM | 636 | * XXX UDB CE trap handler does... -DaveM |
651 | */ | 637 | */ |
652 | printk("PSYCHO%d: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " | 638 | printk("%s: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " |
653 | "UPA_MID[%02lx] was_block(%d)\n", | 639 | "UPA_MID[%02lx] was_block(%d)\n", |
654 | p->index, | 640 | pbm->name, |
655 | (afsr & PSYCHO_CEAFSR_ESYND) >> 48UL, | 641 | (afsr & PSYCHO_CEAFSR_ESYND) >> 48UL, |
656 | (afsr & PSYCHO_CEAFSR_BMSK) >> 32UL, | 642 | (afsr & PSYCHO_CEAFSR_BMSK) >> 32UL, |
657 | (afsr & PSYCHO_CEAFSR_DOFF) >> 29UL, | 643 | (afsr & PSYCHO_CEAFSR_DOFF) >> 29UL, |
658 | (afsr & PSYCHO_CEAFSR_MID) >> 24UL, | 644 | (afsr & PSYCHO_CEAFSR_MID) >> 24UL, |
659 | ((afsr & PSYCHO_CEAFSR_BLK) ? 1 : 0)); | 645 | ((afsr & PSYCHO_CEAFSR_BLK) ? 1 : 0)); |
660 | printk("PSYCHO%d: CE AFAR [%016lx]\n", p->index, afar); | 646 | printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); |
661 | printk("PSYCHO%d: CE Secondary errors [", p->index); | 647 | printk("%s: CE Secondary errors [", pbm->name); |
662 | reported = 0; | 648 | reported = 0; |
663 | if (afsr & PSYCHO_CEAFSR_SPIO) { | 649 | if (afsr & PSYCHO_CEAFSR_SPIO) { |
664 | reported++; | 650 | reported++; |
@@ -773,8 +759,8 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
773 | psycho_write(afsr_reg, error_bits); | 759 | psycho_write(afsr_reg, error_bits); |
774 | 760 | ||
775 | /* Log the error. */ | 761 | /* Log the error. */ |
776 | printk("PSYCHO%d(PBM%c): PCI Error, primary error type[%s]\n", | 762 | printk("%s: PCI Error, primary error type[%s]\n", |
777 | p->index, (is_pbm_a ? 'A' : 'B'), | 763 | pbm->name, |
778 | (((error_bits & PSYCHO_PCIAFSR_PMA) ? | 764 | (((error_bits & PSYCHO_PCIAFSR_PMA) ? |
779 | "Master Abort" : | 765 | "Master Abort" : |
780 | ((error_bits & PSYCHO_PCIAFSR_PTA) ? | 766 | ((error_bits & PSYCHO_PCIAFSR_PTA) ? |
@@ -783,15 +769,13 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
783 | "Excessive Retries" : | 769 | "Excessive Retries" : |
784 | ((error_bits & PSYCHO_PCIAFSR_PPERR) ? | 770 | ((error_bits & PSYCHO_PCIAFSR_PPERR) ? |
785 | "Parity Error" : "???")))))); | 771 | "Parity Error" : "???")))))); |
786 | printk("PSYCHO%d(PBM%c): bytemask[%04lx] UPA_MID[%02lx] was_block(%d)\n", | 772 | printk("%s: bytemask[%04lx] UPA_MID[%02lx] was_block(%d)\n", |
787 | p->index, (is_pbm_a ? 'A' : 'B'), | 773 | pbm->name, |
788 | (afsr & PSYCHO_PCIAFSR_BMSK) >> 32UL, | 774 | (afsr & PSYCHO_PCIAFSR_BMSK) >> 32UL, |
789 | (afsr & PSYCHO_PCIAFSR_MID) >> 25UL, | 775 | (afsr & PSYCHO_PCIAFSR_MID) >> 25UL, |
790 | (afsr & PSYCHO_PCIAFSR_BLK) ? 1 : 0); | 776 | (afsr & PSYCHO_PCIAFSR_BLK) ? 1 : 0); |
791 | printk("PSYCHO%d(PBM%c): PCI AFAR [%016lx]\n", | 777 | printk("%s: PCI AFAR [%016lx]\n", pbm->name, afar); |
792 | p->index, (is_pbm_a ? 'A' : 'B'), afar); | 778 | printk("%s: PCI Secondary errors [", pbm->name); |
793 | printk("PSYCHO%d(PBM%c): PCI Secondary errors [", | ||
794 | p->index, (is_pbm_a ? 'A' : 'B')); | ||
795 | reported = 0; | 779 | reported = 0; |
796 | if (afsr & PSYCHO_PCIAFSR_SMA) { | 780 | if (afsr & PSYCHO_PCIAFSR_SMA) { |
797 | reported++; | 781 | reported++; |
@@ -823,11 +807,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. | 807 | * a bug in the IOMMU support code or a PCI device driver. |
824 | */ | 808 | */ |
825 | if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) { | 809 | if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) { |
826 | psycho_check_iommu_error(p, afsr, afar, PCI_ERR); | 810 | psycho_check_iommu_error(pbm, afsr, afar, PCI_ERR); |
827 | pci_scan_for_target_abort(p, pbm, pbm->pci_bus); | 811 | pci_scan_for_target_abort(pbm, pbm->pci_bus); |
828 | } | 812 | } |
829 | if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA)) | 813 | if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA)) |
830 | pci_scan_for_master_abort(p, pbm, pbm->pci_bus); | 814 | pci_scan_for_master_abort(pbm, pbm->pci_bus); |
831 | 815 | ||
832 | /* For excessive retries, PSYCHO/PBM will abort the device | 816 | /* For excessive retries, PSYCHO/PBM will abort the device |
833 | * and there is no way to specifically check for excessive | 817 | * and there is no way to specifically check for excessive |
@@ -837,7 +821,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
837 | */ | 821 | */ |
838 | 822 | ||
839 | if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR)) | 823 | if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR)) |
840 | pci_scan_for_parity_error(p, pbm, pbm->pci_bus); | 824 | pci_scan_for_parity_error(pbm, pbm->pci_bus); |
841 | 825 | ||
842 | return IRQ_HANDLED; | 826 | return IRQ_HANDLED; |
843 | } | 827 | } |
@@ -847,34 +831,49 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) | |||
847 | #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ | 831 | #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ |
848 | #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ | 832 | #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ |
849 | #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ | 833 | #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ |
850 | static void psycho_register_error_handlers(struct pci_controller_info *p) | 834 | static void psycho_register_error_handlers(struct pci_pbm_info *pbm) |
851 | { | 835 | { |
852 | struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ | ||
853 | struct of_device *op = of_find_device_by_node(pbm->prom_node); | 836 | struct of_device *op = of_find_device_by_node(pbm->prom_node); |
854 | unsigned long base = p->pbm_A.controller_regs; | 837 | unsigned long base = pbm->controller_regs; |
855 | u64 tmp; | 838 | u64 tmp; |
839 | int err; | ||
856 | 840 | ||
857 | if (!op) | 841 | if (!op) |
858 | return; | 842 | return; |
859 | 843 | ||
860 | /* Psycho interrupt property order is: | 844 | /* Psycho interrupt property order is: |
861 | * 0: PCIERR PBM B INO | 845 | * 0: PCIERR INO for this PBM |
862 | * 1: UE ERR | 846 | * 1: UE ERR |
863 | * 2: CE ERR | 847 | * 2: CE ERR |
864 | * 3: POWER FAIL | 848 | * 3: POWER FAIL |
865 | * 4: SPARE HARDWARE | 849 | * 4: SPARE HARDWARE |
866 | * 5: PCIERR PBM A INO | 850 | * 5: POWER MANAGEMENT |
867 | */ | 851 | */ |
868 | 852 | ||
869 | if (op->num_irqs < 6) | 853 | if (op->num_irqs < 6) |
870 | return; | 854 | return; |
871 | 855 | ||
872 | request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED, "PSYCHO UE", p); | 856 | /* We really mean to ignore the return result here. Two |
873 | request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED, "PSYCHO CE", p); | 857 | * PCI controller share the same interrupt numbers and |
874 | request_irq(op->irqs[5], psycho_pcierr_intr, IRQF_SHARED, | 858 | * drive the same front-end hardware. Whichever of the |
875 | "PSYCHO PCIERR-A", &p->pbm_A); | 859 | * two get in here first will register the IRQ handler |
876 | request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED, | 860 | * the second will just error out since we do not pass in |
877 | "PSYCHO PCIERR-B", &p->pbm_B); | 861 | * IRQF_SHARED. |
862 | */ | ||
863 | err = request_irq(op->irqs[1], psycho_ue_intr, 0, | ||
864 | "PSYCHO_UE", pbm); | ||
865 | err = request_irq(op->irqs[2], psycho_ce_intr, 0, | ||
866 | "PSYCHO_CE", pbm); | ||
867 | |||
868 | /* This one, however, ought not to fail. We can just warn | ||
869 | * about it since the system can still operate properly even | ||
870 | * if this fails. | ||
871 | */ | ||
872 | err = request_irq(op->irqs[0], psycho_pcierr_intr, 0, | ||
873 | "PSYCHO_PCIERR", pbm); | ||
874 | if (err) | ||
875 | printk(KERN_WARNING "%s: Could not register PCIERR, " | ||
876 | "err=%d\n", pbm->name, err); | ||
878 | 877 | ||
879 | /* Enable UE and CE interrupts for controller. */ | 878 | /* Enable UE and CE interrupts for controller. */ |
880 | psycho_write(base + PSYCHO_ECC_CTRL, | 879 | psycho_write(base + PSYCHO_ECC_CTRL, |
@@ -918,54 +917,45 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
918 | pci_config_write8(addr, 64); | 917 | pci_config_write8(addr, 64); |
919 | } | 918 | } |
920 | 919 | ||
921 | static void pbm_scan_bus(struct pci_controller_info *p, | 920 | static void psycho_scan_bus(struct pci_pbm_info *pbm) |
922 | struct pci_pbm_info *pbm) | ||
923 | { | 921 | { |
922 | pbm_config_busmastering(pbm); | ||
923 | pbm->is_66mhz_capable = 0; | ||
924 | pbm->pci_bus = pci_scan_one_pbm(pbm); | 924 | 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 | 925 | ||
936 | /* After the PCI bus scan is complete, we can register | 926 | /* After the PCI bus scan is complete, we can register |
937 | * the error interrupt handlers. | 927 | * the error interrupt handlers. |
938 | */ | 928 | */ |
939 | psycho_register_error_handlers(p); | 929 | psycho_register_error_handlers(pbm); |
940 | } | 930 | } |
941 | 931 | ||
942 | static void psycho_iommu_init(struct pci_controller_info *p) | 932 | static void psycho_iommu_init(struct pci_pbm_info *pbm) |
943 | { | 933 | { |
944 | struct iommu *iommu = p->pbm_A.iommu; | 934 | struct iommu *iommu = pbm->iommu; |
945 | unsigned long i; | 935 | unsigned long i; |
946 | u64 control; | 936 | u64 control; |
947 | 937 | ||
948 | /* Register addresses. */ | 938 | /* Register addresses. */ |
949 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; | 939 | iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL; |
950 | iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE; | 940 | iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE; |
951 | iommu->iommu_flush = p->pbm_A.controller_regs + PSYCHO_IOMMU_FLUSH; | 941 | iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH; |
952 | /* PSYCHO's IOMMU lacks ctx flushing. */ | 942 | /* PSYCHO's IOMMU lacks ctx flushing. */ |
953 | iommu->iommu_ctxflush = 0; | 943 | iommu->iommu_ctxflush = 0; |
954 | 944 | ||
955 | /* We use the main control register of PSYCHO as the write | 945 | /* We use the main control register of PSYCHO as the write |
956 | * completion register. | 946 | * completion register. |
957 | */ | 947 | */ |
958 | iommu->write_complete_reg = p->pbm_A.controller_regs + PSYCHO_CONTROL; | 948 | iommu->write_complete_reg = pbm->controller_regs + PSYCHO_CONTROL; |
959 | 949 | ||
960 | /* | 950 | /* |
961 | * Invalidate TLB Entries. | 951 | * Invalidate TLB Entries. |
962 | */ | 952 | */ |
963 | control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); | 953 | control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); |
964 | control |= PSYCHO_IOMMU_CTRL_DENAB; | 954 | control |= PSYCHO_IOMMU_CTRL_DENAB; |
965 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); | 955 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); |
966 | for(i = 0; i < 16; i++) { | 956 | for(i = 0; i < 16; i++) { |
967 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); | 957 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); |
968 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); | 958 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); |
969 | } | 959 | } |
970 | 960 | ||
971 | /* Leave diag mode enabled for full-flushing done | 961 | /* Leave diag mode enabled for full-flushing done |
@@ -973,17 +963,17 @@ static void psycho_iommu_init(struct pci_controller_info *p) | |||
973 | */ | 963 | */ |
974 | pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); | 964 | pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); |
975 | 965 | ||
976 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, | 966 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE, |
977 | __pa(iommu->page_table)); | 967 | __pa(iommu->page_table)); |
978 | 968 | ||
979 | control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); | 969 | control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); |
980 | control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); | 970 | control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); |
981 | control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB); | 971 | control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB); |
982 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); | 972 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); |
983 | 973 | ||
984 | /* If necessary, hook us up for starfire IRQ translations. */ | 974 | /* If necessary, hook us up for starfire IRQ translations. */ |
985 | if (this_is_starfire) | 975 | if (this_is_starfire) |
986 | starfire_hookup(p->pbm_A.portid); | 976 | starfire_hookup(pbm->portid); |
987 | } | 977 | } |
988 | 978 | ||
989 | #define PSYCHO_IRQ_RETRY 0x1a00UL | 979 | #define PSYCHO_IRQ_RETRY 0x1a00UL |
@@ -998,36 +988,35 @@ static void psycho_iommu_init(struct pci_controller_info *p) | |||
998 | #define PSYCHO_PCIDIAG_IPAPAR 0x0000000000000002UL /* Invert PIO address parity */ | 988 | #define PSYCHO_PCIDIAG_IPAPAR 0x0000000000000002UL /* Invert PIO address parity */ |
999 | #define PSYCHO_PCIDIAG_LPBACK 0x0000000000000001UL /* Enable loopback mode */ | 989 | #define PSYCHO_PCIDIAG_LPBACK 0x0000000000000001UL /* Enable loopback mode */ |
1000 | 990 | ||
1001 | static void psycho_controller_hwinit(struct pci_controller_info *p) | 991 | static void psycho_controller_hwinit(struct pci_pbm_info *pbm) |
1002 | { | 992 | { |
1003 | u64 tmp; | 993 | u64 tmp; |
1004 | 994 | ||
1005 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); | 995 | psycho_write(pbm->controller_regs + PSYCHO_IRQ_RETRY, 5); |
1006 | 996 | ||
1007 | /* Enable arbiter for all PCI slots. */ | 997 | /* Enable arbiter for all PCI slots. */ |
1008 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); | 998 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIA_CTRL); |
1009 | tmp |= PSYCHO_PCICTRL_AEN; | 999 | tmp |= PSYCHO_PCICTRL_AEN; |
1010 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL, tmp); | 1000 | psycho_write(pbm->controller_regs + PSYCHO_PCIA_CTRL, tmp); |
1011 | 1001 | ||
1012 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL); | 1002 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIB_CTRL); |
1013 | tmp |= PSYCHO_PCICTRL_AEN; | 1003 | tmp |= PSYCHO_PCICTRL_AEN; |
1014 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL, tmp); | 1004 | psycho_write(pbm->controller_regs + PSYCHO_PCIB_CTRL, tmp); |
1015 | 1005 | ||
1016 | /* Disable DMA write / PIO read synchronization on | 1006 | /* Disable DMA write / PIO read synchronization on |
1017 | * both PCI bus segments. | 1007 | * both PCI bus segments. |
1018 | * [ U2P Erratum 1243770, STP2223BGA data sheet ] | 1008 | * [ U2P Erratum 1243770, STP2223BGA data sheet ] |
1019 | */ | 1009 | */ |
1020 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG); | 1010 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIA_DIAG); |
1021 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; | 1011 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; |
1022 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG, tmp); | 1012 | psycho_write(pbm->controller_regs + PSYCHO_PCIA_DIAG, tmp); |
1023 | 1013 | ||
1024 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG); | 1014 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIB_DIAG); |
1025 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; | 1015 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; |
1026 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); | 1016 | psycho_write(pbm->controller_regs + PSYCHO_PCIB_DIAG, tmp); |
1027 | } | 1017 | } |
1028 | 1018 | ||
1029 | static void psycho_pbm_strbuf_init(struct pci_controller_info *p, | 1019 | static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, |
1030 | struct pci_pbm_info *pbm, | ||
1031 | int is_pbm_a) | 1020 | int is_pbm_a) |
1032 | { | 1021 | { |
1033 | unsigned long base = pbm->controller_regs; | 1022 | unsigned long base = pbm->controller_regs; |
@@ -1088,7 +1077,6 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p, | |||
1088 | static void psycho_pbm_init(struct pci_controller_info *p, | 1077 | static void psycho_pbm_init(struct pci_controller_info *p, |
1089 | struct device_node *dp, int is_pbm_a) | 1078 | struct device_node *dp, int is_pbm_a) |
1090 | { | 1079 | { |
1091 | unsigned int *busrange; | ||
1092 | struct property *prop; | 1080 | struct property *prop; |
1093 | struct pci_pbm_info *pbm; | 1081 | struct pci_pbm_info *pbm; |
1094 | 1082 | ||
@@ -1097,6 +1085,14 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1097 | else | 1085 | else |
1098 | pbm = &p->pbm_B; | 1086 | pbm = &p->pbm_B; |
1099 | 1087 | ||
1088 | pbm->next = pci_pbm_root; | ||
1089 | pci_pbm_root = pbm; | ||
1090 | |||
1091 | pbm->scan_bus = psycho_scan_bus; | ||
1092 | pbm->pci_ops = &psycho_ops; | ||
1093 | |||
1094 | pbm->index = pci_num_pbms++; | ||
1095 | |||
1100 | pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; | 1096 | pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; |
1101 | pbm->chip_version = 0; | 1097 | pbm->chip_version = 0; |
1102 | prop = of_find_property(dp, "version#", NULL); | 1098 | prop = of_find_property(dp, "version#", NULL); |
@@ -1117,12 +1113,9 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1117 | 1113 | ||
1118 | pci_determine_mem_io_space(pbm); | 1114 | pci_determine_mem_io_space(pbm); |
1119 | 1115 | ||
1120 | prop = of_find_property(dp, "bus-range", NULL); | 1116 | pci_get_pbm_props(pbm); |
1121 | busrange = prop->value; | ||
1122 | pbm->pci_first_busno = busrange[0]; | ||
1123 | pbm->pci_last_busno = busrange[1]; | ||
1124 | 1117 | ||
1125 | psycho_pbm_strbuf_init(p, pbm, is_pbm_a); | 1118 | psycho_pbm_strbuf_init(pbm, is_pbm_a); |
1126 | } | 1119 | } |
1127 | 1120 | ||
1128 | #define PSYCHO_CONFIGSPACE 0x001000000UL | 1121 | #define PSYCHO_CONFIGSPACE 0x001000000UL |
@@ -1131,6 +1124,7 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1131 | { | 1124 | { |
1132 | struct linux_prom64_registers *pr_regs; | 1125 | struct linux_prom64_registers *pr_regs; |
1133 | struct pci_controller_info *p; | 1126 | struct pci_controller_info *p; |
1127 | struct pci_pbm_info *pbm; | ||
1134 | struct iommu *iommu; | 1128 | struct iommu *iommu; |
1135 | struct property *prop; | 1129 | struct property *prop; |
1136 | u32 upa_portid; | 1130 | u32 upa_portid; |
@@ -1141,7 +1135,9 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1141 | if (prop) | 1135 | if (prop) |
1142 | upa_portid = *(u32 *) prop->value; | 1136 | upa_portid = *(u32 *) prop->value; |
1143 | 1137 | ||
1144 | for(p = pci_controller_root; p; p = p->next) { | 1138 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1139 | struct pci_controller_info *p = pbm->parent; | ||
1140 | |||
1145 | if (p->pbm_A.portid == upa_portid) { | 1141 | if (p->pbm_A.portid == upa_portid) { |
1146 | is_pbm_a = (p->pbm_A.prom_node == NULL); | 1142 | is_pbm_a = (p->pbm_A.prom_node == NULL); |
1147 | psycho_pbm_init(p, dp, is_pbm_a); | 1143 | psycho_pbm_init(p, dp, is_pbm_a); |
@@ -1161,14 +1157,8 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1161 | } | 1157 | } |
1162 | p->pbm_A.iommu = p->pbm_B.iommu = iommu; | 1158 | p->pbm_A.iommu = p->pbm_B.iommu = iommu; |
1163 | 1159 | ||
1164 | p->next = pci_controller_root; | ||
1165 | pci_controller_root = p; | ||
1166 | |||
1167 | p->pbm_A.portid = upa_portid; | 1160 | p->pbm_A.portid = upa_portid; |
1168 | p->pbm_B.portid = upa_portid; | 1161 | p->pbm_B.portid = upa_portid; |
1169 | p->index = pci_num_controllers++; | ||
1170 | p->scan_bus = psycho_scan_bus; | ||
1171 | p->pci_ops = &psycho_ops; | ||
1172 | 1162 | ||
1173 | prop = of_find_property(dp, "reg", NULL); | 1163 | prop = of_find_property(dp, "reg", NULL); |
1174 | pr_regs = prop->value; | 1164 | pr_regs = prop->value; |
@@ -1185,9 +1175,9 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1185 | */ | 1175 | */ |
1186 | pci_memspace_mask = 0x7fffffffUL; | 1176 | pci_memspace_mask = 0x7fffffffUL; |
1187 | 1177 | ||
1188 | psycho_controller_hwinit(p); | 1178 | psycho_controller_hwinit(&p->pbm_A); |
1189 | 1179 | ||
1190 | psycho_iommu_init(p); | 1180 | psycho_iommu_init(&p->pbm_A); |
1191 | 1181 | ||
1192 | is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); | 1182 | is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); |
1193 | psycho_pbm_init(p, dp, is_pbm_a); | 1183 | psycho_pbm_init(p, dp, is_pbm_a); |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 397862fbd9e1..4cefe6e83b24 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -13,12 +13,12 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | 14 | ||
15 | #include <asm/apb.h> | 15 | #include <asm/apb.h> |
16 | #include <asm/pbm.h> | ||
17 | #include <asm/iommu.h> | 16 | #include <asm/iommu.h> |
18 | #include <asm/irq.h> | 17 | #include <asm/irq.h> |
19 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
20 | #include <asm/oplib.h> | 19 | #include <asm/oplib.h> |
21 | #include <asm/prom.h> | 20 | #include <asm/prom.h> |
21 | #include <asm/of_device.h> | ||
22 | 22 | ||
23 | #include "pci_impl.h" | 23 | #include "pci_impl.h" |
24 | #include "iommu_common.h" | 24 | #include "iommu_common.h" |
@@ -494,11 +494,11 @@ static struct pci_ops sabre_ops = { | |||
494 | }; | 494 | }; |
495 | 495 | ||
496 | /* SABRE error handling support. */ | 496 | /* SABRE error handling support. */ |
497 | static void sabre_check_iommu_error(struct pci_controller_info *p, | 497 | static void sabre_check_iommu_error(struct pci_pbm_info *pbm, |
498 | unsigned long afsr, | 498 | unsigned long afsr, |
499 | unsigned long afar) | 499 | unsigned long afar) |
500 | { | 500 | { |
501 | struct iommu *iommu = p->pbm_A.iommu; | 501 | struct iommu *iommu = pbm->iommu; |
502 | unsigned long iommu_tag[16]; | 502 | unsigned long iommu_tag[16]; |
503 | unsigned long iommu_data[16]; | 503 | unsigned long iommu_data[16]; |
504 | unsigned long flags; | 504 | unsigned long flags; |
@@ -526,8 +526,8 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, | |||
526 | type_string = "Unknown"; | 526 | type_string = "Unknown"; |
527 | break; | 527 | break; |
528 | }; | 528 | }; |
529 | printk("SABRE%d: IOMMU Error, type[%s]\n", | 529 | printk("%s: IOMMU Error, type[%s]\n", |
530 | p->index, type_string); | 530 | pbm->name, type_string); |
531 | 531 | ||
532 | /* Enter diagnostic mode and probe for error'd | 532 | /* Enter diagnostic mode and probe for error'd |
533 | * entries in the IOTLB. | 533 | * entries in the IOTLB. |
@@ -536,7 +536,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, | |||
536 | sabre_write(iommu->iommu_control, | 536 | sabre_write(iommu->iommu_control, |
537 | (control | SABRE_IOMMUCTRL_DENAB)); | 537 | (control | SABRE_IOMMUCTRL_DENAB)); |
538 | for (i = 0; i < 16; i++) { | 538 | for (i = 0; i < 16; i++) { |
539 | unsigned long base = p->pbm_A.controller_regs; | 539 | unsigned long base = pbm->controller_regs; |
540 | 540 | ||
541 | iommu_tag[i] = | 541 | iommu_tag[i] = |
542 | sabre_read(base + SABRE_IOMMU_TAG + (i * 8UL)); | 542 | sabre_read(base + SABRE_IOMMU_TAG + (i * 8UL)); |
@@ -566,13 +566,13 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, | |||
566 | type_string = "Unknown"; | 566 | type_string = "Unknown"; |
567 | break; | 567 | break; |
568 | }; | 568 | }; |
569 | printk("SABRE%d: IOMMU TAG(%d)[RAW(%016lx)error(%s)wr(%d)sz(%dK)vpg(%08lx)]\n", | 569 | printk("%s: IOMMU TAG(%d)[RAW(%016lx)error(%s)wr(%d)sz(%dK)vpg(%08lx)]\n", |
570 | p->index, i, tag, type_string, | 570 | pbm->name, i, tag, type_string, |
571 | ((tag & SABRE_IOMMUTAG_WRITE) ? 1 : 0), | 571 | ((tag & SABRE_IOMMUTAG_WRITE) ? 1 : 0), |
572 | ((tag & SABRE_IOMMUTAG_SIZE) ? 64 : 8), | 572 | ((tag & SABRE_IOMMUTAG_SIZE) ? 64 : 8), |
573 | ((tag & SABRE_IOMMUTAG_VPN) << IOMMU_PAGE_SHIFT)); | 573 | ((tag & SABRE_IOMMUTAG_VPN) << IOMMU_PAGE_SHIFT)); |
574 | printk("SABRE%d: IOMMU DATA(%d)[RAW(%016lx)valid(%d)used(%d)cache(%d)ppg(%016lx)\n", | 574 | printk("%s: IOMMU DATA(%d)[RAW(%016lx)valid(%d)used(%d)cache(%d)ppg(%016lx)\n", |
575 | p->index, i, data, | 575 | pbm->name, i, data, |
576 | ((data & SABRE_IOMMUDATA_VALID) ? 1 : 0), | 576 | ((data & SABRE_IOMMUDATA_VALID) ? 1 : 0), |
577 | ((data & SABRE_IOMMUDATA_USED) ? 1 : 0), | 577 | ((data & SABRE_IOMMUDATA_USED) ? 1 : 0), |
578 | ((data & SABRE_IOMMUDATA_CACHE) ? 1 : 0), | 578 | ((data & SABRE_IOMMUDATA_CACHE) ? 1 : 0), |
@@ -584,9 +584,9 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, | |||
584 | 584 | ||
585 | static irqreturn_t sabre_ue_intr(int irq, void *dev_id) | 585 | static irqreturn_t sabre_ue_intr(int irq, void *dev_id) |
586 | { | 586 | { |
587 | struct pci_controller_info *p = dev_id; | 587 | struct pci_pbm_info *pbm = dev_id; |
588 | unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR; | 588 | unsigned long afsr_reg = pbm->controller_regs + SABRE_UE_AFSR; |
589 | unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR; | 589 | unsigned long afar_reg = pbm->controller_regs + SABRE_UECE_AFAR; |
590 | unsigned long afsr, afar, error_bits; | 590 | unsigned long afsr, afar, error_bits; |
591 | int reported; | 591 | int reported; |
592 | 592 | ||
@@ -604,21 +604,21 @@ static irqreturn_t sabre_ue_intr(int irq, void *dev_id) | |||
604 | sabre_write(afsr_reg, error_bits); | 604 | sabre_write(afsr_reg, error_bits); |
605 | 605 | ||
606 | /* Log the error. */ | 606 | /* Log the error. */ |
607 | printk("SABRE%d: Uncorrectable Error, primary error type[%s%s]\n", | 607 | printk("%s: Uncorrectable Error, primary error type[%s%s]\n", |
608 | p->index, | 608 | pbm->name, |
609 | ((error_bits & SABRE_UEAFSR_PDRD) ? | 609 | ((error_bits & SABRE_UEAFSR_PDRD) ? |
610 | "DMA Read" : | 610 | "DMA Read" : |
611 | ((error_bits & SABRE_UEAFSR_PDWR) ? | 611 | ((error_bits & SABRE_UEAFSR_PDWR) ? |
612 | "DMA Write" : "???")), | 612 | "DMA Write" : "???")), |
613 | ((error_bits & SABRE_UEAFSR_PDTE) ? | 613 | ((error_bits & SABRE_UEAFSR_PDTE) ? |
614 | ":Translation Error" : "")); | 614 | ":Translation Error" : "")); |
615 | printk("SABRE%d: bytemask[%04lx] dword_offset[%lx] was_block(%d)\n", | 615 | printk("%s: bytemask[%04lx] dword_offset[%lx] was_block(%d)\n", |
616 | p->index, | 616 | pbm->name, |
617 | (afsr & SABRE_UEAFSR_BMSK) >> 32UL, | 617 | (afsr & SABRE_UEAFSR_BMSK) >> 32UL, |
618 | (afsr & SABRE_UEAFSR_OFF) >> 29UL, | 618 | (afsr & SABRE_UEAFSR_OFF) >> 29UL, |
619 | ((afsr & SABRE_UEAFSR_BLK) ? 1 : 0)); | 619 | ((afsr & SABRE_UEAFSR_BLK) ? 1 : 0)); |
620 | printk("SABRE%d: UE AFAR [%016lx]\n", p->index, afar); | 620 | printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); |
621 | printk("SABRE%d: UE Secondary errors [", p->index); | 621 | printk("%s: UE Secondary errors [", pbm->name); |
622 | reported = 0; | 622 | reported = 0; |
623 | if (afsr & SABRE_UEAFSR_SDRD) { | 623 | if (afsr & SABRE_UEAFSR_SDRD) { |
624 | reported++; | 624 | reported++; |
@@ -637,16 +637,16 @@ static irqreturn_t sabre_ue_intr(int irq, void *dev_id) | |||
637 | printk("]\n"); | 637 | printk("]\n"); |
638 | 638 | ||
639 | /* Interrogate IOMMU for error status. */ | 639 | /* Interrogate IOMMU for error status. */ |
640 | sabre_check_iommu_error(p, afsr, afar); | 640 | sabre_check_iommu_error(pbm, afsr, afar); |
641 | 641 | ||
642 | return IRQ_HANDLED; | 642 | return IRQ_HANDLED; |
643 | } | 643 | } |
644 | 644 | ||
645 | static irqreturn_t sabre_ce_intr(int irq, void *dev_id) | 645 | static irqreturn_t sabre_ce_intr(int irq, void *dev_id) |
646 | { | 646 | { |
647 | struct pci_controller_info *p = dev_id; | 647 | struct pci_pbm_info *pbm = dev_id; |
648 | unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR; | 648 | unsigned long afsr_reg = pbm->controller_regs + SABRE_CE_AFSR; |
649 | unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR; | 649 | unsigned long afar_reg = pbm->controller_regs + SABRE_UECE_AFAR; |
650 | unsigned long afsr, afar, error_bits; | 650 | unsigned long afsr, afar, error_bits; |
651 | int reported; | 651 | int reported; |
652 | 652 | ||
@@ -663,8 +663,8 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) | |||
663 | sabre_write(afsr_reg, error_bits); | 663 | sabre_write(afsr_reg, error_bits); |
664 | 664 | ||
665 | /* Log the error. */ | 665 | /* Log the error. */ |
666 | printk("SABRE%d: Correctable Error, primary error type[%s]\n", | 666 | printk("%s: Correctable Error, primary error type[%s]\n", |
667 | p->index, | 667 | pbm->name, |
668 | ((error_bits & SABRE_CEAFSR_PDRD) ? | 668 | ((error_bits & SABRE_CEAFSR_PDRD) ? |
669 | "DMA Read" : | 669 | "DMA Read" : |
670 | ((error_bits & SABRE_CEAFSR_PDWR) ? | 670 | ((error_bits & SABRE_CEAFSR_PDWR) ? |
@@ -673,15 +673,15 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) | |||
673 | /* XXX Use syndrome and afar to print out module string just like | 673 | /* XXX Use syndrome and afar to print out module string just like |
674 | * XXX UDB CE trap handler does... -DaveM | 674 | * XXX UDB CE trap handler does... -DaveM |
675 | */ | 675 | */ |
676 | printk("SABRE%d: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " | 676 | printk("%s: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " |
677 | "was_block(%d)\n", | 677 | "was_block(%d)\n", |
678 | p->index, | 678 | pbm->name, |
679 | (afsr & SABRE_CEAFSR_ESYND) >> 48UL, | 679 | (afsr & SABRE_CEAFSR_ESYND) >> 48UL, |
680 | (afsr & SABRE_CEAFSR_BMSK) >> 32UL, | 680 | (afsr & SABRE_CEAFSR_BMSK) >> 32UL, |
681 | (afsr & SABRE_CEAFSR_OFF) >> 29UL, | 681 | (afsr & SABRE_CEAFSR_OFF) >> 29UL, |
682 | ((afsr & SABRE_CEAFSR_BLK) ? 1 : 0)); | 682 | ((afsr & SABRE_CEAFSR_BLK) ? 1 : 0)); |
683 | printk("SABRE%d: CE AFAR [%016lx]\n", p->index, afar); | 683 | printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); |
684 | printk("SABRE%d: CE Secondary errors [", p->index); | 684 | printk("%s: CE Secondary errors [", pbm->name); |
685 | reported = 0; | 685 | reported = 0; |
686 | if (afsr & SABRE_CEAFSR_SDRD) { | 686 | if (afsr & SABRE_CEAFSR_SDRD) { |
687 | reported++; | 687 | reported++; |
@@ -698,13 +698,13 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) | |||
698 | return IRQ_HANDLED; | 698 | return IRQ_HANDLED; |
699 | } | 699 | } |
700 | 700 | ||
701 | static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) | 701 | static irqreturn_t sabre_pcierr_intr_other(struct pci_pbm_info *pbm) |
702 | { | 702 | { |
703 | unsigned long csr_reg, csr, csr_error_bits; | 703 | unsigned long csr_reg, csr, csr_error_bits; |
704 | irqreturn_t ret = IRQ_NONE; | 704 | irqreturn_t ret = IRQ_NONE; |
705 | u16 stat; | 705 | u16 stat; |
706 | 706 | ||
707 | csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL; | 707 | csr_reg = pbm->controller_regs + SABRE_PCICTRL; |
708 | csr = sabre_read(csr_reg); | 708 | csr = sabre_read(csr_reg); |
709 | csr_error_bits = | 709 | csr_error_bits = |
710 | csr & SABRE_PCICTRL_SERR; | 710 | csr & SABRE_PCICTRL_SERR; |
@@ -714,8 +714,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) | |||
714 | 714 | ||
715 | /* Log 'em. */ | 715 | /* Log 'em. */ |
716 | if (csr_error_bits & SABRE_PCICTRL_SERR) | 716 | if (csr_error_bits & SABRE_PCICTRL_SERR) |
717 | printk("SABRE%d: PCI SERR signal asserted.\n", | 717 | printk("%s: PCI SERR signal asserted.\n", |
718 | p->index); | 718 | pbm->name); |
719 | ret = IRQ_HANDLED; | 719 | ret = IRQ_HANDLED; |
720 | } | 720 | } |
721 | pci_bus_read_config_word(sabre_root_bus, 0, | 721 | pci_bus_read_config_word(sabre_root_bus, 0, |
@@ -725,8 +725,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) | |||
725 | PCI_STATUS_REC_TARGET_ABORT | | 725 | PCI_STATUS_REC_TARGET_ABORT | |
726 | PCI_STATUS_REC_MASTER_ABORT | | 726 | PCI_STATUS_REC_MASTER_ABORT | |
727 | PCI_STATUS_SIG_SYSTEM_ERROR)) { | 727 | PCI_STATUS_SIG_SYSTEM_ERROR)) { |
728 | printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", | 728 | printk("%s: PCI bus error, PCI_STATUS[%04x]\n", |
729 | p->index, stat); | 729 | pbm->name, stat); |
730 | pci_bus_write_config_word(sabre_root_bus, 0, | 730 | pci_bus_write_config_word(sabre_root_bus, 0, |
731 | PCI_STATUS, 0xffff); | 731 | PCI_STATUS, 0xffff); |
732 | ret = IRQ_HANDLED; | 732 | ret = IRQ_HANDLED; |
@@ -736,13 +736,13 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) | |||
736 | 736 | ||
737 | static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | 737 | static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) |
738 | { | 738 | { |
739 | struct pci_controller_info *p = dev_id; | 739 | struct pci_pbm_info *pbm = dev_id; |
740 | unsigned long afsr_reg, afar_reg; | 740 | unsigned long afsr_reg, afar_reg; |
741 | unsigned long afsr, afar, error_bits; | 741 | unsigned long afsr, afar, error_bits; |
742 | int reported; | 742 | int reported; |
743 | 743 | ||
744 | afsr_reg = p->pbm_A.controller_regs + SABRE_PIOAFSR; | 744 | afsr_reg = pbm->controller_regs + SABRE_PIOAFSR; |
745 | afar_reg = p->pbm_A.controller_regs + SABRE_PIOAFAR; | 745 | afar_reg = pbm->controller_regs + SABRE_PIOAFAR; |
746 | 746 | ||
747 | /* Latch error status. */ | 747 | /* Latch error status. */ |
748 | afar = sabre_read(afar_reg); | 748 | afar = sabre_read(afar_reg); |
@@ -755,12 +755,12 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
755 | SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA | | 755 | SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA | |
756 | SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR); | 756 | SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR); |
757 | if (!error_bits) | 757 | if (!error_bits) |
758 | return sabre_pcierr_intr_other(p); | 758 | return sabre_pcierr_intr_other(pbm); |
759 | sabre_write(afsr_reg, error_bits); | 759 | sabre_write(afsr_reg, error_bits); |
760 | 760 | ||
761 | /* Log the error. */ | 761 | /* Log the error. */ |
762 | printk("SABRE%d: PCI Error, primary error type[%s]\n", | 762 | printk("%s: PCI Error, primary error type[%s]\n", |
763 | p->index, | 763 | pbm->name, |
764 | (((error_bits & SABRE_PIOAFSR_PMA) ? | 764 | (((error_bits & SABRE_PIOAFSR_PMA) ? |
765 | "Master Abort" : | 765 | "Master Abort" : |
766 | ((error_bits & SABRE_PIOAFSR_PTA) ? | 766 | ((error_bits & SABRE_PIOAFSR_PTA) ? |
@@ -769,12 +769,12 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
769 | "Excessive Retries" : | 769 | "Excessive Retries" : |
770 | ((error_bits & SABRE_PIOAFSR_PPERR) ? | 770 | ((error_bits & SABRE_PIOAFSR_PPERR) ? |
771 | "Parity Error" : "???")))))); | 771 | "Parity Error" : "???")))))); |
772 | printk("SABRE%d: bytemask[%04lx] was_block(%d)\n", | 772 | printk("%s: bytemask[%04lx] was_block(%d)\n", |
773 | p->index, | 773 | pbm->name, |
774 | (afsr & SABRE_PIOAFSR_BMSK) >> 32UL, | 774 | (afsr & SABRE_PIOAFSR_BMSK) >> 32UL, |
775 | (afsr & SABRE_PIOAFSR_BLK) ? 1 : 0); | 775 | (afsr & SABRE_PIOAFSR_BLK) ? 1 : 0); |
776 | printk("SABRE%d: PCI AFAR [%016lx]\n", p->index, afar); | 776 | printk("%s: PCI AFAR [%016lx]\n", pbm->name, afar); |
777 | printk("SABRE%d: PCI Secondary errors [", p->index); | 777 | printk("%s: PCI Secondary errors [", pbm->name); |
778 | reported = 0; | 778 | reported = 0; |
779 | if (afsr & SABRE_PIOAFSR_SMA) { | 779 | if (afsr & SABRE_PIOAFSR_SMA) { |
780 | reported++; | 780 | reported++; |
@@ -806,11 +806,11 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
806 | * a bug in the IOMMU support code or a PCI device driver. | 806 | * a bug in the IOMMU support code or a PCI device driver. |
807 | */ | 807 | */ |
808 | if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) { | 808 | if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) { |
809 | sabre_check_iommu_error(p, afsr, afar); | 809 | sabre_check_iommu_error(pbm, afsr, afar); |
810 | pci_scan_for_target_abort(p, &p->pbm_A, p->pbm_A.pci_bus); | 810 | pci_scan_for_target_abort(pbm, pbm->pci_bus); |
811 | } | 811 | } |
812 | if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) | 812 | if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) |
813 | pci_scan_for_master_abort(p, &p->pbm_A, p->pbm_A.pci_bus); | 813 | pci_scan_for_master_abort(pbm, pbm->pci_bus); |
814 | 814 | ||
815 | /* For excessive retries, SABRE/PBM will abort the device | 815 | /* For excessive retries, SABRE/PBM will abort the device |
816 | * and there is no way to specifically check for excessive | 816 | * and there is no way to specifically check for excessive |
@@ -820,18 +820,18 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
820 | */ | 820 | */ |
821 | 821 | ||
822 | if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) | 822 | if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) |
823 | pci_scan_for_parity_error(p, &p->pbm_A, p->pbm_A.pci_bus); | 823 | pci_scan_for_parity_error(pbm, pbm->pci_bus); |
824 | 824 | ||
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 */ | ||
831 | struct device_node *dp = pbm->prom_node; | 830 | struct device_node *dp = pbm->prom_node; |
832 | struct of_device *op; | 831 | struct of_device *op; |
833 | unsigned long base = pbm->controller_regs; | 832 | unsigned long base = pbm->controller_regs; |
834 | u64 tmp; | 833 | u64 tmp; |
834 | int err; | ||
835 | 835 | ||
836 | if (pbm->chip_type == PBM_CHIP_TYPE_SABRE) | 836 | if (pbm->chip_type == PBM_CHIP_TYPE_SABRE) |
837 | dp = dp->parent; | 837 | dp = dp->parent; |
@@ -858,22 +858,31 @@ 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 | err = request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm); |
862 | if (err) | ||
863 | printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n", | ||
864 | pbm->name, err); | ||
862 | 865 | ||
863 | sabre_write(base + SABRE_CE_AFSR, | 866 | sabre_write(base + SABRE_CE_AFSR, |
864 | (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | | 867 | (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | |
865 | SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); | 868 | SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); |
866 | 869 | ||
867 | request_irq(op->irqs[2], sabre_ce_intr, IRQF_SHARED, "SABRE CE", p); | 870 | err = request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm); |
868 | request_irq(op->irqs[0], sabre_pcierr_intr, IRQF_SHARED, | 871 | if (err) |
869 | "SABRE PCIERR", p); | 872 | printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n", |
873 | pbm->name, err); | ||
874 | err = request_irq(op->irqs[0], sabre_pcierr_intr, 0, | ||
875 | "SABRE_PCIERR", pbm); | ||
876 | if (err) | ||
877 | printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n", | ||
878 | pbm->name, err); | ||
870 | 879 | ||
871 | tmp = sabre_read(base + SABRE_PCICTRL); | 880 | tmp = sabre_read(base + SABRE_PCICTRL); |
872 | tmp |= SABRE_PCICTRL_ERREN; | 881 | tmp |= SABRE_PCICTRL_ERREN; |
873 | sabre_write(base + SABRE_PCICTRL, tmp); | 882 | sabre_write(base + SABRE_PCICTRL, tmp); |
874 | } | 883 | } |
875 | 884 | ||
876 | static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) | 885 | static void apb_init(struct pci_bus *sabre_bus) |
877 | { | 886 | { |
878 | struct pci_dev *pdev; | 887 | struct pci_dev *pdev; |
879 | 888 | ||
@@ -909,7 +918,7 @@ static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) | |||
909 | } | 918 | } |
910 | } | 919 | } |
911 | 920 | ||
912 | static void sabre_scan_bus(struct pci_controller_info *p) | 921 | static void sabre_scan_bus(struct pci_pbm_info *pbm) |
913 | { | 922 | { |
914 | static int once; | 923 | static int once; |
915 | struct pci_bus *pbus; | 924 | struct pci_bus *pbus; |
@@ -918,7 +927,7 @@ static void sabre_scan_bus(struct pci_controller_info *p) | |||
918 | * at 66Mhz, but the front side of APB runs at 33Mhz | 927 | * at 66Mhz, but the front side of APB runs at 33Mhz |
919 | * for both segments. | 928 | * for both segments. |
920 | */ | 929 | */ |
921 | p->pbm_A.is_66mhz_capable = 0; | 930 | pbm->is_66mhz_capable = 0; |
922 | 931 | ||
923 | /* This driver has not been verified to handle | 932 | /* This driver has not been verified to handle |
924 | * multiple SABREs yet, so trap this. | 933 | * multiple SABREs yet, so trap this. |
@@ -932,41 +941,41 @@ static void sabre_scan_bus(struct pci_controller_info *p) | |||
932 | } | 941 | } |
933 | once++; | 942 | once++; |
934 | 943 | ||
935 | pbus = pci_scan_one_pbm(&p->pbm_A); | 944 | pbus = pci_scan_one_pbm(pbm); |
936 | if (!pbus) | 945 | if (!pbus) |
937 | return; | 946 | return; |
938 | 947 | ||
939 | sabre_root_bus = pbus; | 948 | sabre_root_bus = pbus; |
940 | 949 | ||
941 | apb_init(p, pbus); | 950 | apb_init(pbus); |
942 | 951 | ||
943 | sabre_register_error_handlers(p); | 952 | sabre_register_error_handlers(pbm); |
944 | } | 953 | } |
945 | 954 | ||
946 | static void sabre_iommu_init(struct pci_controller_info *p, | 955 | static void sabre_iommu_init(struct pci_pbm_info *pbm, |
947 | int tsbsize, unsigned long dvma_offset, | 956 | int tsbsize, unsigned long dvma_offset, |
948 | u32 dma_mask) | 957 | u32 dma_mask) |
949 | { | 958 | { |
950 | struct iommu *iommu = p->pbm_A.iommu; | 959 | struct iommu *iommu = pbm->iommu; |
951 | unsigned long i; | 960 | unsigned long i; |
952 | u64 control; | 961 | u64 control; |
953 | 962 | ||
954 | /* Register addresses. */ | 963 | /* Register addresses. */ |
955 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; | 964 | iommu->iommu_control = pbm->controller_regs + SABRE_IOMMU_CONTROL; |
956 | iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE; | 965 | iommu->iommu_tsbbase = pbm->controller_regs + SABRE_IOMMU_TSBBASE; |
957 | iommu->iommu_flush = p->pbm_A.controller_regs + SABRE_IOMMU_FLUSH; | 966 | iommu->iommu_flush = pbm->controller_regs + SABRE_IOMMU_FLUSH; |
958 | iommu->write_complete_reg = p->pbm_A.controller_regs + SABRE_WRSYNC; | 967 | iommu->write_complete_reg = pbm->controller_regs + SABRE_WRSYNC; |
959 | /* Sabre's IOMMU lacks ctx flushing. */ | 968 | /* Sabre's IOMMU lacks ctx flushing. */ |
960 | iommu->iommu_ctxflush = 0; | 969 | iommu->iommu_ctxflush = 0; |
961 | 970 | ||
962 | /* Invalidate TLB Entries. */ | 971 | /* Invalidate TLB Entries. */ |
963 | control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); | 972 | control = sabre_read(pbm->controller_regs + SABRE_IOMMU_CONTROL); |
964 | control |= SABRE_IOMMUCTRL_DENAB; | 973 | control |= SABRE_IOMMUCTRL_DENAB; |
965 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); | 974 | sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control); |
966 | 975 | ||
967 | for(i = 0; i < 16; i++) { | 976 | for(i = 0; i < 16; i++) { |
968 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0); | 977 | sabre_write(pbm->controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0); |
969 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0); | 978 | sabre_write(pbm->controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0); |
970 | } | 979 | } |
971 | 980 | ||
972 | /* Leave diag mode enabled for full-flushing done | 981 | /* Leave diag mode enabled for full-flushing done |
@@ -974,10 +983,10 @@ static void sabre_iommu_init(struct pci_controller_info *p, | |||
974 | */ | 983 | */ |
975 | pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask); | 984 | pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask); |
976 | 985 | ||
977 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, | 986 | sabre_write(pbm->controller_regs + SABRE_IOMMU_TSBBASE, |
978 | __pa(iommu->page_table)); | 987 | __pa(iommu->page_table)); |
979 | 988 | ||
980 | control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); | 989 | control = sabre_read(pbm->controller_regs + SABRE_IOMMU_CONTROL); |
981 | control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ); | 990 | control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ); |
982 | control |= SABRE_IOMMUCTRL_ENAB; | 991 | control |= SABRE_IOMMUCTRL_ENAB; |
983 | switch(tsbsize) { | 992 | switch(tsbsize) { |
@@ -992,22 +1001,23 @@ static void sabre_iommu_init(struct pci_controller_info *p, | |||
992 | prom_halt(); | 1001 | prom_halt(); |
993 | break; | 1002 | break; |
994 | } | 1003 | } |
995 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); | 1004 | sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control); |
996 | } | 1005 | } |
997 | 1006 | ||
998 | static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp) | 1007 | static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *pbm, struct device_node *dp) |
999 | { | 1008 | { |
1000 | struct pci_pbm_info *pbm; | ||
1001 | |||
1002 | pbm = &p->pbm_A; | ||
1003 | pbm->name = dp->full_name; | 1009 | pbm->name = dp->full_name; |
1004 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | 1010 | printk("%s: SABRE PCI Bus Module\n", pbm->name); |
1005 | 1011 | ||
1012 | pbm->scan_bus = sabre_scan_bus; | ||
1013 | pbm->pci_ops = &sabre_ops; | ||
1014 | |||
1015 | pbm->index = pci_num_pbms++; | ||
1016 | |||
1006 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; | 1017 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; |
1007 | pbm->parent = p; | 1018 | pbm->parent = p; |
1008 | pbm->prom_node = dp; | 1019 | pbm->prom_node = dp; |
1009 | pbm->pci_first_busno = p->pci_first_busno; | 1020 | pci_get_pbm_props(pbm); |
1010 | pbm->pci_last_busno = p->pci_last_busno; | ||
1011 | 1021 | ||
1012 | pci_determine_mem_io_space(pbm); | 1022 | pci_determine_mem_io_space(pbm); |
1013 | } | 1023 | } |
@@ -1016,9 +1026,9 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1016 | { | 1026 | { |
1017 | const struct linux_prom64_registers *pr_regs; | 1027 | const struct linux_prom64_registers *pr_regs; |
1018 | struct pci_controller_info *p; | 1028 | struct pci_controller_info *p; |
1029 | struct pci_pbm_info *pbm; | ||
1019 | struct iommu *iommu; | 1030 | struct iommu *iommu; |
1020 | int tsbsize; | 1031 | int tsbsize; |
1021 | const u32 *busrange; | ||
1022 | const u32 *vdma; | 1032 | const u32 *vdma; |
1023 | u32 upa_portid, dma_mask; | 1033 | u32 upa_portid, dma_mask; |
1024 | u64 clear_irq; | 1034 | u64 clear_irq; |
@@ -1053,17 +1063,15 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1053 | prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); | 1063 | prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); |
1054 | prom_halt(); | 1064 | prom_halt(); |
1055 | } | 1065 | } |
1056 | p->pbm_A.iommu = iommu; | 1066 | pbm = &p->pbm_A; |
1067 | pbm->iommu = iommu; | ||
1057 | 1068 | ||
1058 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); | 1069 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); |
1059 | 1070 | ||
1060 | p->next = pci_controller_root; | 1071 | pbm->next = pci_pbm_root; |
1061 | pci_controller_root = p; | 1072 | pci_pbm_root = pbm; |
1062 | 1073 | ||
1063 | p->pbm_A.portid = upa_portid; | 1074 | pbm->portid = upa_portid; |
1064 | p->index = pci_num_controllers++; | ||
1065 | p->scan_bus = sabre_scan_bus; | ||
1066 | p->pci_ops = &sabre_ops; | ||
1067 | 1075 | ||
1068 | /* | 1076 | /* |
1069 | * Map in SABRE register set and report the presence of this SABRE. | 1077 | * Map in SABRE register set and report the presence of this SABRE. |
@@ -1074,26 +1082,26 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1074 | /* | 1082 | /* |
1075 | * First REG in property is base of entire SABRE register space. | 1083 | * First REG in property is base of entire SABRE register space. |
1076 | */ | 1084 | */ |
1077 | p->pbm_A.controller_regs = pr_regs[0].phys_addr; | 1085 | pbm->controller_regs = pr_regs[0].phys_addr; |
1078 | 1086 | ||
1079 | /* Clear interrupts */ | 1087 | /* Clear interrupts */ |
1080 | 1088 | ||
1081 | /* PCI first */ | 1089 | /* PCI first */ |
1082 | for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8) | 1090 | for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8) |
1083 | sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL); | 1091 | sabre_write(pbm->controller_regs + clear_irq, 0x0UL); |
1084 | 1092 | ||
1085 | /* Then OBIO */ | 1093 | /* Then OBIO */ |
1086 | for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8) | 1094 | for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8) |
1087 | sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL); | 1095 | sabre_write(pbm->controller_regs + clear_irq, 0x0UL); |
1088 | 1096 | ||
1089 | /* Error interrupts are enabled later after the bus scan. */ | 1097 | /* Error interrupts are enabled later after the bus scan. */ |
1090 | sabre_write(p->pbm_A.controller_regs + SABRE_PCICTRL, | 1098 | sabre_write(pbm->controller_regs + SABRE_PCICTRL, |
1091 | (SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR | | 1099 | (SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR | |
1092 | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); | 1100 | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); |
1093 | 1101 | ||
1094 | /* Now map in PCI config space for entire SABRE. */ | 1102 | /* Now map in PCI config space for entire SABRE. */ |
1095 | p->pbm_A.config_space = | 1103 | pbm->config_space = |
1096 | (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); | 1104 | (pbm->controller_regs + SABRE_CONFIGSPACE); |
1097 | 1105 | ||
1098 | vdma = of_get_property(dp, "virtual-dma", NULL); | 1106 | vdma = of_get_property(dp, "virtual-dma", NULL); |
1099 | 1107 | ||
@@ -1117,14 +1125,10 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1117 | prom_halt(); | 1125 | prom_halt(); |
1118 | } | 1126 | } |
1119 | 1127 | ||
1120 | sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); | 1128 | sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask); |
1121 | |||
1122 | busrange = of_get_property(dp, "bus-range", NULL); | ||
1123 | p->pci_first_busno = busrange[0]; | ||
1124 | p->pci_last_busno = busrange[1]; | ||
1125 | 1129 | ||
1126 | /* | 1130 | /* |
1127 | * Look for APB underneath. | 1131 | * Look for APB underneath. |
1128 | */ | 1132 | */ |
1129 | sabre_pbm_init(p, dp); | 1133 | sabre_pbm_init(p, pbm, dp); |
1130 | } | 1134 | } |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 91a7385e5d32..e375d72b8eed 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -10,12 +10,13 @@ | |||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | 12 | ||
13 | #include <asm/pbm.h> | ||
14 | #include <asm/iommu.h> | 13 | #include <asm/iommu.h> |
15 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
16 | #include <asm/upa.h> | 15 | #include <asm/upa.h> |
17 | #include <asm/pstate.h> | 16 | #include <asm/pstate.h> |
18 | #include <asm/prom.h> | 17 | #include <asm/prom.h> |
18 | #include <asm/of_device.h> | ||
19 | #include <asm/oplib.h> | ||
19 | 20 | ||
20 | #include "pci_impl.h" | 21 | #include "pci_impl.h" |
21 | #include "iommu_common.h" | 22 | #include "iommu_common.h" |
@@ -238,25 +239,6 @@ static unsigned long stc_line_buf[16]; | |||
238 | #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ | 239 | #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ |
239 | #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ | 240 | #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ |
240 | 241 | ||
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 */ | 242 | #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ |
261 | #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ | 243 | #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ |
262 | #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ | 244 | #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ |
@@ -522,9 +504,10 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, | |||
522 | 504 | ||
523 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | 505 | static irqreturn_t schizo_ue_intr(int irq, void *dev_id) |
524 | { | 506 | { |
525 | struct pci_controller_info *p = dev_id; | 507 | struct pci_pbm_info *pbm = dev_id; |
526 | unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR; | 508 | struct pci_controller_info *p = pbm->parent; |
527 | unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFAR; | 509 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; |
510 | unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; | ||
528 | unsigned long afsr, afar, error_bits; | 511 | unsigned long afsr, afar, error_bits; |
529 | int reported, limit; | 512 | int reported, limit; |
530 | 513 | ||
@@ -549,28 +532,28 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | |||
549 | schizo_write(afsr_reg, error_bits); | 532 | schizo_write(afsr_reg, error_bits); |
550 | 533 | ||
551 | /* Log the error. */ | 534 | /* Log the error. */ |
552 | printk("PCI%d: Uncorrectable Error, primary error type[%s]\n", | 535 | printk("%s: Uncorrectable Error, primary error type[%s]\n", |
553 | p->index, | 536 | pbm->name, |
554 | (((error_bits & SCHIZO_UEAFSR_PPIO) ? | 537 | (((error_bits & SCHIZO_UEAFSR_PPIO) ? |
555 | "PIO" : | 538 | "PIO" : |
556 | ((error_bits & SCHIZO_UEAFSR_PDRD) ? | 539 | ((error_bits & SCHIZO_UEAFSR_PDRD) ? |
557 | "DMA Read" : | 540 | "DMA Read" : |
558 | ((error_bits & SCHIZO_UEAFSR_PDWR) ? | 541 | ((error_bits & SCHIZO_UEAFSR_PDWR) ? |
559 | "DMA Write" : "???"))))); | 542 | "DMA Write" : "???"))))); |
560 | printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", | 543 | printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", |
561 | p->index, | 544 | pbm->name, |
562 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, | 545 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, |
563 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, | 546 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, |
564 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); | 547 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); |
565 | printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", | 548 | printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", |
566 | p->index, | 549 | pbm->name, |
567 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, | 550 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, |
568 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, | 551 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, |
569 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, | 552 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, |
570 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, | 553 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, |
571 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); | 554 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); |
572 | printk("PCI%d: UE AFAR [%016lx]\n", p->index, afar); | 555 | printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); |
573 | printk("PCI%d: UE Secondary errors [", p->index); | 556 | printk("%s: UE Secondary errors [", pbm->name); |
574 | reported = 0; | 557 | reported = 0; |
575 | if (afsr & SCHIZO_UEAFSR_SPIO) { | 558 | if (afsr & SCHIZO_UEAFSR_SPIO) { |
576 | reported++; | 559 | reported++; |
@@ -610,9 +593,9 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) | |||
610 | 593 | ||
611 | static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | 594 | static irqreturn_t schizo_ce_intr(int irq, void *dev_id) |
612 | { | 595 | { |
613 | struct pci_controller_info *p = dev_id; | 596 | struct pci_pbm_info *pbm = dev_id; |
614 | unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR; | 597 | unsigned long afsr_reg = pbm->controller_regs + SCHIZO_CE_AFSR; |
615 | unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFAR; | 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 | ||
@@ -637,8 +620,8 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | |||
637 | schizo_write(afsr_reg, error_bits); | 620 | schizo_write(afsr_reg, error_bits); |
638 | 621 | ||
639 | /* Log the error. */ | 622 | /* Log the error. */ |
640 | printk("PCI%d: Correctable Error, primary error type[%s]\n", | 623 | printk("%s: Correctable Error, primary error type[%s]\n", |
641 | p->index, | 624 | pbm->name, |
642 | (((error_bits & SCHIZO_CEAFSR_PPIO) ? | 625 | (((error_bits & SCHIZO_CEAFSR_PPIO) ? |
643 | "PIO" : | 626 | "PIO" : |
644 | ((error_bits & SCHIZO_CEAFSR_PDRD) ? | 627 | ((error_bits & SCHIZO_CEAFSR_PDRD) ? |
@@ -649,20 +632,20 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id) | |||
649 | /* XXX Use syndrome and afar to print out module string just like | 632 | /* XXX Use syndrome and afar to print out module string just like |
650 | * XXX UDB CE trap handler does... -DaveM | 633 | * XXX UDB CE trap handler does... -DaveM |
651 | */ | 634 | */ |
652 | printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", | 635 | printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", |
653 | p->index, | 636 | pbm->name, |
654 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, | 637 | (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, |
655 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, | 638 | (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, |
656 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); | 639 | (afsr & SCHIZO_UEAFSR_AID) >> 24UL); |
657 | printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", | 640 | printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", |
658 | p->index, | 641 | pbm->name, |
659 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, | 642 | (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, |
660 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, | 643 | (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, |
661 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, | 644 | (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, |
662 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, | 645 | (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, |
663 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); | 646 | (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); |
664 | printk("PCI%d: CE AFAR [%016lx]\n", p->index, afar); | 647 | printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); |
665 | printk("PCI%d: CE Secondary errors [", p->index); | 648 | printk("%s: CE Secondary errors [", pbm->name); |
666 | reported = 0; | 649 | reported = 0; |
667 | if (afsr & SCHIZO_CEAFSR_SPIO) { | 650 | if (afsr & SCHIZO_CEAFSR_SPIO) { |
668 | reported++; | 651 | reported++; |
@@ -881,10 +864,10 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
881 | */ | 864 | */ |
882 | if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { | 865 | if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { |
883 | schizo_check_iommu_error(p, PCI_ERR); | 866 | schizo_check_iommu_error(p, PCI_ERR); |
884 | pci_scan_for_target_abort(p, pbm, pbm->pci_bus); | 867 | pci_scan_for_target_abort(pbm, pbm->pci_bus); |
885 | } | 868 | } |
886 | if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) | 869 | if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) |
887 | pci_scan_for_master_abort(p, pbm, pbm->pci_bus); | 870 | pci_scan_for_master_abort(pbm, pbm->pci_bus); |
888 | 871 | ||
889 | /* For excessive retries, PSYCHO/PBM will abort the device | 872 | /* For excessive retries, PSYCHO/PBM will abort the device |
890 | * and there is no way to specifically check for excessive | 873 | * and there is no way to specifically check for excessive |
@@ -894,7 +877,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) | |||
894 | */ | 877 | */ |
895 | 878 | ||
896 | if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) | 879 | if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) |
897 | pci_scan_for_parity_error(p, pbm, pbm->pci_bus); | 880 | pci_scan_for_parity_error(pbm, pbm->pci_bus); |
898 | 881 | ||
899 | return IRQ_HANDLED; | 882 | return IRQ_HANDLED; |
900 | } | 883 | } |
@@ -940,22 +923,23 @@ 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)) { |
951 | printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", | 935 | printk("%s: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", |
952 | p->index, errlog); | 936 | pbm->name, errlog); |
953 | 937 | ||
954 | return IRQ_HANDLED; | 938 | return IRQ_HANDLED; |
955 | } | 939 | } |
956 | 940 | ||
957 | printk("PCI%d: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", | 941 | printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", |
958 | p->index); | 942 | pbm->name); |
959 | schizo_check_iommu_error(p, SAFARI_ERR); | 943 | schizo_check_iommu_error(p, SAFARI_ERR); |
960 | 944 | ||
961 | return IRQ_HANDLED; | 945 | return IRQ_HANDLED; |
@@ -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,11 +980,11 @@ 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; |
987 | int err; | ||
994 | 988 | ||
995 | /* Tomatillo IRQ property layout is: | 989 | /* Tomatillo IRQ property layout is: |
996 | * 0: PCIERR | 990 | * 0: PCIERR |
@@ -1000,44 +994,42 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1000 | * 4: POWER FAIL? | 994 | * 4: POWER FAIL? |
1001 | */ | 995 | */ |
1002 | 996 | ||
1003 | pbm = pbm_for_ino(p, SCHIZO_UE_INO); | 997 | if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { |
1004 | op = of_find_device_by_node(pbm->prom_node); | 998 | err = request_irq(op->irqs[1], schizo_ue_intr, 0, |
1005 | if (op) | 999 | "TOMATILLO_UE", pbm); |
1006 | request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, | 1000 | if (err) |
1007 | "TOMATILLO_UE", p); | 1001 | printk(KERN_WARNING "%s: Could not register UE, " |
1008 | 1002 | "err=%d\n", pbm->name, err); | |
1009 | pbm = pbm_for_ino(p, SCHIZO_CE_INO); | 1003 | } |
1010 | op = of_find_device_by_node(pbm->prom_node); | 1004 | if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { |
1011 | if (op) | 1005 | err = request_irq(op->irqs[2], schizo_ce_intr, 0, |
1012 | request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, | 1006 | "TOMATILLO_CE", pbm); |
1013 | "TOMATILLO CE", p); | 1007 | if (err) |
1014 | 1008 | printk(KERN_WARNING "%s: Could not register CE, " | |
1015 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); | 1009 | "err=%d\n", pbm->name, err); |
1016 | op = of_find_device_by_node(pbm->prom_node); | 1010 | } |
1017 | if (op) | 1011 | err = 0; |
1018 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1012 | if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { |
1019 | "TOMATILLO PCIERR-A", pbm); | 1013 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1020 | 1014 | "TOMATILLO_PCIERR", pbm); | |
1021 | 1015 | } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { | |
1022 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); | 1016 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1023 | op = of_find_device_by_node(pbm->prom_node); | 1017 | "TOMATILLO_PCIERR", pbm); |
1024 | if (op) | 1018 | } |
1025 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1019 | if (err) |
1026 | "TOMATILLO PCIERR-B", pbm); | 1020 | printk(KERN_WARNING "%s: Could not register PCIERR, " |
1027 | 1021 | "err=%d\n", pbm->name, err); | |
1028 | pbm = pbm_for_ino(p, SCHIZO_SERR_INO); | 1022 | |
1029 | op = of_find_device_by_node(pbm->prom_node); | 1023 | if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { |
1030 | if (op) | 1024 | err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, |
1031 | request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, | 1025 | "TOMATILLO_SERR", pbm); |
1032 | "TOMATILLO SERR", p); | 1026 | if (err) |
1027 | printk(KERN_WARNING "%s: Could not register SERR, " | ||
1028 | "err=%d\n", pbm->name, err); | ||
1029 | } | ||
1033 | 1030 | ||
1034 | /* Enable UE and CE interrupts for controller. */ | 1031 | /* Enable UE and CE interrupts for controller. */ |
1035 | schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, | 1032 | schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, |
1036 | (SCHIZO_ECCCTRL_EE | | ||
1037 | SCHIZO_ECCCTRL_UE | | ||
1038 | SCHIZO_ECCCTRL_CE)); | ||
1039 | |||
1040 | schizo_write(p->pbm_B.controller_regs + SCHIZO_ECC_CTRL, | ||
1041 | (SCHIZO_ECCCTRL_EE | | 1033 | (SCHIZO_ECCCTRL_EE | |
1042 | SCHIZO_ECCCTRL_UE | | 1034 | SCHIZO_ECCCTRL_UE | |
1043 | SCHIZO_ECCCTRL_CE)); | 1035 | SCHIZO_ECCCTRL_CE)); |
@@ -1053,15 +1045,10 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1053 | 1045 | ||
1054 | err_no_mask = SCHIZO_PCICTRL_DTO_ERR; | 1046 | err_no_mask = SCHIZO_PCICTRL_DTO_ERR; |
1055 | 1047 | ||
1056 | tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); | 1048 | 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; | 1049 | tmp |= err_mask; |
1063 | tmp &= ~err_no_mask; | 1050 | tmp &= ~err_no_mask; |
1064 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); | 1051 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); |
1065 | 1052 | ||
1066 | err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | 1053 | err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | |
1067 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | 1054 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | |
@@ -1070,8 +1057,7 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1070 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | | 1057 | SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | |
1071 | SCHIZO_PCIAFSR_STTO); | 1058 | SCHIZO_PCIAFSR_STTO); |
1072 | 1059 | ||
1073 | schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, err_mask); | 1060 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, err_mask); |
1074 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, err_mask); | ||
1075 | 1061 | ||
1076 | err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | | 1062 | err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | |
1077 | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | | 1063 | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | |
@@ -1083,22 +1069,18 @@ static void tomatillo_register_error_handlers(struct pci_controller_info *p) | |||
1083 | BUS_ERROR_APERR | BUS_ERROR_UNMAP | | 1069 | BUS_ERROR_APERR | BUS_ERROR_UNMAP | |
1084 | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); | 1070 | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); |
1085 | 1071 | ||
1086 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, | 1072 | 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)); | 1073 | (SCHIZO_SAFERRCTRL_EN | err_mask)); |
1090 | 1074 | ||
1091 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, | 1075 | 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))); | 1076 | (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); |
1095 | } | 1077 | } |
1096 | 1078 | ||
1097 | static void schizo_register_error_handlers(struct pci_controller_info *p) | 1079 | static void schizo_register_error_handlers(struct pci_pbm_info *pbm) |
1098 | { | 1080 | { |
1099 | struct pci_pbm_info *pbm; | 1081 | 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; | 1082 | u64 tmp, err_mask, err_no_mask; |
1083 | int err; | ||
1102 | 1084 | ||
1103 | /* Schizo IRQ property layout is: | 1085 | /* Schizo IRQ property layout is: |
1104 | * 0: PCIERR | 1086 | * 0: PCIERR |
@@ -1108,39 +1090,42 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1108 | * 4: POWER FAIL? | 1090 | * 4: POWER FAIL? |
1109 | */ | 1091 | */ |
1110 | 1092 | ||
1111 | pbm = pbm_for_ino(p, SCHIZO_UE_INO); | 1093 | if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { |
1112 | op = of_find_device_by_node(pbm->prom_node); | 1094 | err = request_irq(op->irqs[1], schizo_ue_intr, 0, |
1113 | if (op) | 1095 | "SCHIZO_UE", pbm); |
1114 | request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, | 1096 | if (err) |
1115 | "SCHIZO_UE", p); | 1097 | printk(KERN_WARNING "%s: Could not register UE, " |
1116 | 1098 | "err=%d\n", pbm->name, err); | |
1117 | pbm = pbm_for_ino(p, SCHIZO_CE_INO); | 1099 | } |
1118 | op = of_find_device_by_node(pbm->prom_node); | 1100 | if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { |
1119 | if (op) | 1101 | err = request_irq(op->irqs[2], schizo_ce_intr, 0, |
1120 | request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, | 1102 | "SCHIZO_CE", pbm); |
1121 | "SCHIZO CE", p); | 1103 | if (err) |
1122 | 1104 | printk(KERN_WARNING "%s: Could not register CE, " | |
1123 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); | 1105 | "err=%d\n", pbm->name, err); |
1124 | op = of_find_device_by_node(pbm->prom_node); | 1106 | } |
1125 | if (op) | 1107 | err = 0; |
1126 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1108 | if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { |
1127 | "SCHIZO PCIERR-A", pbm); | 1109 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1128 | 1110 | "SCHIZO_PCIERR", pbm); | |
1129 | 1111 | } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { | |
1130 | pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); | 1112 | err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, |
1131 | op = of_find_device_by_node(pbm->prom_node); | 1113 | "SCHIZO_PCIERR", pbm); |
1132 | if (op) | 1114 | } |
1133 | request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, | 1115 | if (err) |
1134 | "SCHIZO PCIERR-B", pbm); | 1116 | printk(KERN_WARNING "%s: Could not register PCIERR, " |
1135 | 1117 | "err=%d\n", pbm->name, err); | |
1136 | pbm = pbm_for_ino(p, SCHIZO_SERR_INO); | 1118 | |
1137 | op = of_find_device_by_node(pbm->prom_node); | 1119 | if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { |
1138 | if (op) | 1120 | err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, |
1139 | request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, | 1121 | "SCHIZO_SERR", pbm); |
1140 | "SCHIZO SERR", p); | 1122 | if (err) |
1123 | printk(KERN_WARNING "%s: Could not register SERR, " | ||
1124 | "err=%d\n", pbm->name, err); | ||
1125 | } | ||
1141 | 1126 | ||
1142 | /* Enable UE and CE interrupts for controller. */ | 1127 | /* Enable UE and CE interrupts for controller. */ |
1143 | schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, | 1128 | schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, |
1144 | (SCHIZO_ECCCTRL_EE | | 1129 | (SCHIZO_ECCCTRL_EE | |
1145 | SCHIZO_ECCCTRL_UE | | 1130 | SCHIZO_ECCCTRL_UE | |
1146 | SCHIZO_ECCCTRL_CE)); | 1131 | SCHIZO_ECCCTRL_CE)); |
@@ -1159,25 +1144,12 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1159 | /* Enable PCI Error interrupts and clear error | 1144 | /* Enable PCI Error interrupts and clear error |
1160 | * bits for each PBM. | 1145 | * bits for each PBM. |
1161 | */ | 1146 | */ |
1162 | tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); | 1147 | 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; | 1148 | tmp |= err_mask; |
1177 | tmp &= ~err_no_mask; | 1149 | tmp &= ~err_no_mask; |
1178 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); | 1150 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); |
1179 | 1151 | ||
1180 | schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, | 1152 | schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, |
1181 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | | 1153 | (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | |
1182 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | | 1154 | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | |
1183 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | | 1155 | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | |
@@ -1210,11 +1182,8 @@ static void schizo_register_error_handlers(struct pci_controller_info *p) | |||
1210 | BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); | 1182 | BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); |
1211 | #endif | 1183 | #endif |
1212 | 1184 | ||
1213 | schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, | 1185 | schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, |
1214 | (SCHIZO_SAFERRCTRL_EN | err_mask)); | 1186 | (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 | } | 1187 | } |
1219 | 1188 | ||
1220 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) | 1189 | static void pbm_config_busmastering(struct pci_pbm_info *pbm) |
@@ -1234,27 +1203,19 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) | |||
1234 | pci_config_write8(addr, 64); | 1203 | pci_config_write8(addr, 64); |
1235 | } | 1204 | } |
1236 | 1205 | ||
1237 | static void schizo_scan_bus(struct pci_controller_info *p) | 1206 | static void schizo_scan_bus(struct pci_pbm_info *pbm) |
1238 | { | 1207 | { |
1239 | pbm_config_busmastering(&p->pbm_B); | 1208 | pbm_config_busmastering(pbm); |
1240 | p->pbm_B.is_66mhz_capable = | 1209 | pbm->is_66mhz_capable = |
1241 | (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) | 1210 | (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); | 1211 | != NULL); |
1247 | 1212 | ||
1248 | p->pbm_B.pci_bus = pci_scan_one_pbm(&p->pbm_B); | 1213 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
1249 | p->pbm_A.pci_bus = pci_scan_one_pbm(&p->pbm_A); | ||
1250 | 1214 | ||
1251 | /* After the PCI bus scan is complete, we can register | 1215 | if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) |
1252 | * the error interrupt handlers. | 1216 | 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 | 1217 | else |
1257 | schizo_register_error_handlers(p); | 1218 | schizo_register_error_handlers(pbm); |
1258 | } | 1219 | } |
1259 | 1220 | ||
1260 | #define SCHIZO_STRBUF_CONTROL (0x02800UL) | 1221 | #define SCHIZO_STRBUF_CONTROL (0x02800UL) |
@@ -1491,10 +1452,8 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1491 | int chip_type) | 1452 | int chip_type) |
1492 | { | 1453 | { |
1493 | const struct linux_prom64_registers *regs; | 1454 | const struct linux_prom64_registers *regs; |
1494 | const unsigned int *busrange; | ||
1495 | struct pci_pbm_info *pbm; | 1455 | struct pci_pbm_info *pbm; |
1496 | const char *chipset_name; | 1456 | const char *chipset_name; |
1497 | const u32 *ino_bitmap; | ||
1498 | int is_pbm_a; | 1457 | int is_pbm_a; |
1499 | 1458 | ||
1500 | switch (chip_type) { | 1459 | switch (chip_type) { |
@@ -1531,6 +1490,14 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1531 | else | 1490 | else |
1532 | pbm = &p->pbm_B; | 1491 | pbm = &p->pbm_B; |
1533 | 1492 | ||
1493 | pbm->next = pci_pbm_root; | ||
1494 | pci_pbm_root = pbm; | ||
1495 | |||
1496 | pbm->scan_bus = schizo_scan_bus; | ||
1497 | pbm->pci_ops = &schizo_ops; | ||
1498 | |||
1499 | pbm->index = pci_num_pbms++; | ||
1500 | |||
1534 | pbm->portid = portid; | 1501 | pbm->portid = portid; |
1535 | pbm->parent = p; | 1502 | pbm->parent = p; |
1536 | pbm->prom_node = dp; | 1503 | pbm->prom_node = dp; |
@@ -1555,13 +1522,7 @@ static void schizo_pbm_init(struct pci_controller_info *p, | |||
1555 | 1522 | ||
1556 | pci_determine_mem_io_space(pbm); | 1523 | pci_determine_mem_io_space(pbm); |
1557 | 1524 | ||
1558 | ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); | 1525 | pci_get_pbm_props(pbm); |
1559 | pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | | ||
1560 | ((u64)ino_bitmap[0] << 0UL)); | ||
1561 | |||
1562 | busrange = of_get_property(dp, "bus-range", NULL); | ||
1563 | pbm->pci_first_busno = busrange[0]; | ||
1564 | pbm->pci_last_busno = busrange[1]; | ||
1565 | 1526 | ||
1566 | schizo_pbm_iommu_init(pbm); | 1527 | schizo_pbm_iommu_init(pbm); |
1567 | schizo_pbm_strbuf_init(pbm); | 1528 | schizo_pbm_strbuf_init(pbm); |
@@ -1580,23 +1541,15 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) | |||
1580 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) | 1541 | static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) |
1581 | { | 1542 | { |
1582 | struct pci_controller_info *p; | 1543 | struct pci_controller_info *p; |
1544 | struct pci_pbm_info *pbm; | ||
1583 | struct iommu *iommu; | 1545 | struct iommu *iommu; |
1584 | u32 portid; | 1546 | u32 portid; |
1585 | 1547 | ||
1586 | portid = of_getintprop_default(dp, "portid", 0xff); | 1548 | portid = of_getintprop_default(dp, "portid", 0xff); |
1587 | 1549 | ||
1588 | for (p = pci_controller_root; p; p = p->next) { | 1550 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1589 | struct pci_pbm_info *pbm; | ||
1590 | |||
1591 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
1592 | continue; | ||
1593 | |||
1594 | pbm = (p->pbm_A.prom_node ? | ||
1595 | &p->pbm_A : | ||
1596 | &p->pbm_B); | ||
1597 | |||
1598 | if (portid_compare(pbm->portid, portid, chip_type)) { | 1551 | if (portid_compare(pbm->portid, portid, chip_type)) { |
1599 | schizo_pbm_init(p, dp, portid, chip_type); | 1552 | schizo_pbm_init(pbm->parent, dp, portid, chip_type); |
1600 | return; | 1553 | return; |
1601 | } | 1554 | } |
1602 | } | 1555 | } |
@@ -1617,13 +1570,6 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ | |||
1617 | 1570 | ||
1618 | p->pbm_B.iommu = iommu; | 1571 | p->pbm_B.iommu = iommu; |
1619 | 1572 | ||
1620 | p->next = pci_controller_root; | ||
1621 | pci_controller_root = p; | ||
1622 | |||
1623 | p->index = pci_num_controllers++; | ||
1624 | p->scan_bus = schizo_scan_bus; | ||
1625 | p->pci_ops = &schizo_ops; | ||
1626 | |||
1627 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ | 1573 | /* Like PSYCHO we have a 2GB aligned area for memory space. */ |
1628 | pci_memspace_mask = 0x7fffffffUL; | 1574 | pci_memspace_mask = 0x7fffffffUL; |
1629 | 1575 | ||
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 1ccf4c9a9a43..0c76a8891a96 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/msi.h> | 14 | #include <linux/msi.h> |
15 | 15 | ||
16 | #include <asm/pbm.h> | ||
17 | #include <asm/iommu.h> | 16 | #include <asm/iommu.h> |
18 | #include <asm/irq.h> | 17 | #include <asm/irq.h> |
19 | #include <asm/upa.h> | 18 | #include <asm/upa.h> |
@@ -677,29 +676,15 @@ static struct pci_ops pci_sun4v_ops = { | |||
677 | }; | 676 | }; |
678 | 677 | ||
679 | 678 | ||
680 | static void pbm_scan_bus(struct pci_controller_info *p, | 679 | 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 | { | 680 | { |
688 | struct property *prop; | 681 | struct property *prop; |
689 | struct device_node *dp; | 682 | struct device_node *dp; |
690 | 683 | ||
691 | if ((dp = p->pbm_A.prom_node) != NULL) { | 684 | dp = pbm->prom_node; |
692 | prop = of_find_property(dp, "66mhz-capable", NULL); | 685 | prop = of_find_property(dp, "66mhz-capable", NULL); |
693 | p->pbm_A.is_66mhz_capable = (prop != NULL); | 686 | pbm->is_66mhz_capable = (prop != NULL); |
694 | 687 | 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 | 688 | ||
704 | /* XXX register error interrupt handlers XXX */ | 689 | /* XXX register error interrupt handlers XXX */ |
705 | } | 690 | } |
@@ -802,20 +787,6 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | |||
802 | pbm->name, sz); | 787 | pbm->name, sz); |
803 | } | 788 | } |
804 | 789 | ||
805 | static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) | ||
806 | { | ||
807 | struct property *prop; | ||
808 | unsigned int *busrange; | ||
809 | |||
810 | prop = of_find_property(pbm->prom_node, "bus-range", NULL); | ||
811 | |||
812 | busrange = prop->value; | ||
813 | |||
814 | pbm->pci_first_busno = busrange[0]; | ||
815 | pbm->pci_last_busno = busrange[1]; | ||
816 | |||
817 | } | ||
818 | |||
819 | #ifdef CONFIG_PCI_MSI | 790 | #ifdef CONFIG_PCI_MSI |
820 | struct pci_sun4v_msiq_entry { | 791 | struct pci_sun4v_msiq_entry { |
821 | u64 version_type; | 792 | u64 version_type; |
@@ -1019,114 +990,6 @@ h_error: | |||
1019 | return -EINVAL; | 990 | return -EINVAL; |
1020 | } | 991 | } |
1021 | 992 | ||
1022 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | ||
1023 | { | ||
1024 | const u32 *val; | ||
1025 | int len; | ||
1026 | |||
1027 | val = of_get_property(pbm->prom_node, "#msi-eqs", &len); | ||
1028 | if (!val || len != 4) | ||
1029 | goto no_msi; | ||
1030 | pbm->msiq_num = *val; | ||
1031 | if (pbm->msiq_num) { | ||
1032 | const struct msiq_prop { | ||
1033 | u32 first_msiq; | ||
1034 | u32 num_msiq; | ||
1035 | u32 first_devino; | ||
1036 | } *mqp; | ||
1037 | const struct msi_range_prop { | ||
1038 | u32 first_msi; | ||
1039 | u32 num_msi; | ||
1040 | } *mrng; | ||
1041 | const struct addr_range_prop { | ||
1042 | u32 msi32_high; | ||
1043 | u32 msi32_low; | ||
1044 | u32 msi32_len; | ||
1045 | u32 msi64_high; | ||
1046 | u32 msi64_low; | ||
1047 | u32 msi64_len; | ||
1048 | } *arng; | ||
1049 | |||
1050 | val = of_get_property(pbm->prom_node, "msi-eq-size", &len); | ||
1051 | if (!val || len != 4) | ||
1052 | goto no_msi; | ||
1053 | |||
1054 | pbm->msiq_ent_count = *val; | ||
1055 | |||
1056 | mqp = of_get_property(pbm->prom_node, | ||
1057 | "msi-eq-to-devino", &len); | ||
1058 | if (!mqp || len != sizeof(struct msiq_prop)) | ||
1059 | goto no_msi; | ||
1060 | |||
1061 | pbm->msiq_first = mqp->first_msiq; | ||
1062 | pbm->msiq_first_devino = mqp->first_devino; | ||
1063 | |||
1064 | val = of_get_property(pbm->prom_node, "#msi", &len); | ||
1065 | if (!val || len != 4) | ||
1066 | goto no_msi; | ||
1067 | pbm->msi_num = *val; | ||
1068 | |||
1069 | mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); | ||
1070 | if (!mrng || len != sizeof(struct msi_range_prop)) | ||
1071 | goto no_msi; | ||
1072 | pbm->msi_first = mrng->first_msi; | ||
1073 | |||
1074 | val = of_get_property(pbm->prom_node, "msi-data-mask", &len); | ||
1075 | if (!val || len != 4) | ||
1076 | goto no_msi; | ||
1077 | pbm->msi_data_mask = *val; | ||
1078 | |||
1079 | val = of_get_property(pbm->prom_node, "msix-data-width", &len); | ||
1080 | if (!val || len != 4) | ||
1081 | goto no_msi; | ||
1082 | pbm->msix_data_width = *val; | ||
1083 | |||
1084 | arng = of_get_property(pbm->prom_node, "msi-address-ranges", | ||
1085 | &len); | ||
1086 | if (!arng || len != sizeof(struct addr_range_prop)) | ||
1087 | goto no_msi; | ||
1088 | pbm->msi32_start = ((u64)arng->msi32_high << 32) | | ||
1089 | (u64) arng->msi32_low; | ||
1090 | pbm->msi64_start = ((u64)arng->msi64_high << 32) | | ||
1091 | (u64) arng->msi64_low; | ||
1092 | pbm->msi32_len = arng->msi32_len; | ||
1093 | pbm->msi64_len = arng->msi64_len; | ||
1094 | |||
1095 | if (msi_bitmap_alloc(pbm)) | ||
1096 | goto no_msi; | ||
1097 | |||
1098 | if (msi_queue_alloc(pbm)) { | ||
1099 | msi_bitmap_free(pbm); | ||
1100 | goto no_msi; | ||
1101 | } | ||
1102 | |||
1103 | printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " | ||
1104 | "devino[0x%x]\n", | ||
1105 | pbm->name, | ||
1106 | pbm->msiq_first, pbm->msiq_num, | ||
1107 | pbm->msiq_ent_count, | ||
1108 | pbm->msiq_first_devino); | ||
1109 | printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " | ||
1110 | "width[%u]\n", | ||
1111 | pbm->name, | ||
1112 | pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, | ||
1113 | pbm->msix_data_width); | ||
1114 | printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " | ||
1115 | "addr64[0x%lx:0x%x]\n", | ||
1116 | pbm->name, | ||
1117 | pbm->msi32_start, pbm->msi32_len, | ||
1118 | pbm->msi64_start, pbm->msi64_len); | ||
1119 | printk(KERN_INFO "%s: MSI queues at RA [%p]\n", | ||
1120 | pbm->name, | ||
1121 | pbm->msi_queues); | ||
1122 | } | ||
1123 | |||
1124 | return; | ||
1125 | |||
1126 | no_msi: | ||
1127 | pbm->msiq_num = 0; | ||
1128 | printk(KERN_INFO "%s: No MSI support.\n", pbm->name); | ||
1129 | } | ||
1130 | 993 | ||
1131 | static int alloc_msi(struct pci_pbm_info *pbm) | 994 | static int alloc_msi(struct pci_pbm_info *pbm) |
1132 | { | 995 | { |
@@ -1245,6 +1108,117 @@ static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq, | |||
1245 | */ | 1108 | */ |
1246 | sun4v_destroy_msi(virt_irq); | 1109 | sun4v_destroy_msi(virt_irq); |
1247 | } | 1110 | } |
1111 | |||
1112 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | ||
1113 | { | ||
1114 | const u32 *val; | ||
1115 | int len; | ||
1116 | |||
1117 | val = of_get_property(pbm->prom_node, "#msi-eqs", &len); | ||
1118 | if (!val || len != 4) | ||
1119 | goto no_msi; | ||
1120 | pbm->msiq_num = *val; | ||
1121 | if (pbm->msiq_num) { | ||
1122 | const struct msiq_prop { | ||
1123 | u32 first_msiq; | ||
1124 | u32 num_msiq; | ||
1125 | u32 first_devino; | ||
1126 | } *mqp; | ||
1127 | const struct msi_range_prop { | ||
1128 | u32 first_msi; | ||
1129 | u32 num_msi; | ||
1130 | } *mrng; | ||
1131 | const struct addr_range_prop { | ||
1132 | u32 msi32_high; | ||
1133 | u32 msi32_low; | ||
1134 | u32 msi32_len; | ||
1135 | u32 msi64_high; | ||
1136 | u32 msi64_low; | ||
1137 | u32 msi64_len; | ||
1138 | } *arng; | ||
1139 | |||
1140 | val = of_get_property(pbm->prom_node, "msi-eq-size", &len); | ||
1141 | if (!val || len != 4) | ||
1142 | goto no_msi; | ||
1143 | |||
1144 | pbm->msiq_ent_count = *val; | ||
1145 | |||
1146 | mqp = of_get_property(pbm->prom_node, | ||
1147 | "msi-eq-to-devino", &len); | ||
1148 | if (!mqp || len != sizeof(struct msiq_prop)) | ||
1149 | goto no_msi; | ||
1150 | |||
1151 | pbm->msiq_first = mqp->first_msiq; | ||
1152 | pbm->msiq_first_devino = mqp->first_devino; | ||
1153 | |||
1154 | val = of_get_property(pbm->prom_node, "#msi", &len); | ||
1155 | if (!val || len != 4) | ||
1156 | goto no_msi; | ||
1157 | pbm->msi_num = *val; | ||
1158 | |||
1159 | mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); | ||
1160 | if (!mrng || len != sizeof(struct msi_range_prop)) | ||
1161 | goto no_msi; | ||
1162 | pbm->msi_first = mrng->first_msi; | ||
1163 | |||
1164 | val = of_get_property(pbm->prom_node, "msi-data-mask", &len); | ||
1165 | if (!val || len != 4) | ||
1166 | goto no_msi; | ||
1167 | pbm->msi_data_mask = *val; | ||
1168 | |||
1169 | val = of_get_property(pbm->prom_node, "msix-data-width", &len); | ||
1170 | if (!val || len != 4) | ||
1171 | goto no_msi; | ||
1172 | pbm->msix_data_width = *val; | ||
1173 | |||
1174 | arng = of_get_property(pbm->prom_node, "msi-address-ranges", | ||
1175 | &len); | ||
1176 | if (!arng || len != sizeof(struct addr_range_prop)) | ||
1177 | goto no_msi; | ||
1178 | pbm->msi32_start = ((u64)arng->msi32_high << 32) | | ||
1179 | (u64) arng->msi32_low; | ||
1180 | pbm->msi64_start = ((u64)arng->msi64_high << 32) | | ||
1181 | (u64) arng->msi64_low; | ||
1182 | pbm->msi32_len = arng->msi32_len; | ||
1183 | pbm->msi64_len = arng->msi64_len; | ||
1184 | |||
1185 | if (msi_bitmap_alloc(pbm)) | ||
1186 | goto no_msi; | ||
1187 | |||
1188 | if (msi_queue_alloc(pbm)) { | ||
1189 | msi_bitmap_free(pbm); | ||
1190 | goto no_msi; | ||
1191 | } | ||
1192 | |||
1193 | printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " | ||
1194 | "devino[0x%x]\n", | ||
1195 | pbm->name, | ||
1196 | pbm->msiq_first, pbm->msiq_num, | ||
1197 | pbm->msiq_ent_count, | ||
1198 | pbm->msiq_first_devino); | ||
1199 | printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " | ||
1200 | "width[%u]\n", | ||
1201 | pbm->name, | ||
1202 | pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, | ||
1203 | pbm->msix_data_width); | ||
1204 | printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " | ||
1205 | "addr64[0x%lx:0x%x]\n", | ||
1206 | pbm->name, | ||
1207 | pbm->msi32_start, pbm->msi32_len, | ||
1208 | pbm->msi64_start, pbm->msi64_len); | ||
1209 | printk(KERN_INFO "%s: MSI queues at RA [%p]\n", | ||
1210 | pbm->name, | ||
1211 | pbm->msi_queues); | ||
1212 | } | ||
1213 | pbm->setup_msi_irq = pci_sun4v_setup_msi_irq; | ||
1214 | pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq; | ||
1215 | |||
1216 | return; | ||
1217 | |||
1218 | no_msi: | ||
1219 | pbm->msiq_num = 0; | ||
1220 | printk(KERN_INFO "%s: No MSI support.\n", pbm->name); | ||
1221 | } | ||
1248 | #else /* CONFIG_PCI_MSI */ | 1222 | #else /* CONFIG_PCI_MSI */ |
1249 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | 1223 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) |
1250 | { | 1224 | { |
@@ -1260,6 +1234,14 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1260 | else | 1234 | else |
1261 | pbm = &p->pbm_A; | 1235 | pbm = &p->pbm_A; |
1262 | 1236 | ||
1237 | pbm->next = pci_pbm_root; | ||
1238 | pci_pbm_root = pbm; | ||
1239 | |||
1240 | pbm->scan_bus = pci_sun4v_scan_bus; | ||
1241 | pbm->pci_ops = &pci_sun4v_ops; | ||
1242 | |||
1243 | pbm->index = pci_num_pbms++; | ||
1244 | |||
1263 | pbm->parent = p; | 1245 | pbm->parent = p; |
1264 | pbm->prom_node = dp; | 1246 | pbm->prom_node = dp; |
1265 | 1247 | ||
@@ -1271,7 +1253,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1271 | 1253 | ||
1272 | pci_determine_mem_io_space(pbm); | 1254 | pci_determine_mem_io_space(pbm); |
1273 | 1255 | ||
1274 | pci_sun4v_get_bus_range(pbm); | 1256 | pci_get_pbm_props(pbm); |
1275 | pci_sun4v_iommu_init(pbm); | 1257 | pci_sun4v_iommu_init(pbm); |
1276 | pci_sun4v_msi_init(pbm); | 1258 | pci_sun4v_msi_init(pbm); |
1277 | } | 1259 | } |
@@ -1279,6 +1261,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1279 | void sun4v_pci_init(struct device_node *dp, char *model_name) | 1261 | void sun4v_pci_init(struct device_node *dp, char *model_name) |
1280 | { | 1262 | { |
1281 | struct pci_controller_info *p; | 1263 | struct pci_controller_info *p; |
1264 | struct pci_pbm_info *pbm; | ||
1282 | struct iommu *iommu; | 1265 | struct iommu *iommu; |
1283 | struct property *prop; | 1266 | struct property *prop; |
1284 | struct linux_prom64_registers *regs; | 1267 | struct linux_prom64_registers *regs; |
@@ -1290,18 +1273,9 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) | |||
1290 | 1273 | ||
1291 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; | 1274 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; |
1292 | 1275 | ||
1293 | for (p = pci_controller_root; p; p = p->next) { | 1276 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { |
1294 | struct pci_pbm_info *pbm; | ||
1295 | |||
1296 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
1297 | continue; | ||
1298 | |||
1299 | pbm = (p->pbm_A.prom_node ? | ||
1300 | &p->pbm_A : | ||
1301 | &p->pbm_B); | ||
1302 | |||
1303 | if (pbm->devhandle == (devhandle ^ 0x40)) { | 1277 | if (pbm->devhandle == (devhandle ^ 0x40)) { |
1304 | pci_sun4v_pbm_init(p, dp, devhandle); | 1278 | pci_sun4v_pbm_init(pbm->parent, dp, devhandle); |
1305 | return; | 1279 | return; |
1306 | } | 1280 | } |
1307 | } | 1281 | } |
@@ -1331,18 +1305,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) | |||
1331 | 1305 | ||
1332 | p->pbm_B.iommu = iommu; | 1306 | p->pbm_B.iommu = iommu; |
1333 | 1307 | ||
1334 | p->next = pci_controller_root; | ||
1335 | pci_controller_root = p; | ||
1336 | |||
1337 | p->index = pci_num_controllers++; | ||
1338 | |||
1339 | p->scan_bus = pci_sun4v_scan_bus; | ||
1340 | #ifdef CONFIG_PCI_MSI | ||
1341 | p->setup_msi_irq = pci_sun4v_setup_msi_irq; | ||
1342 | p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; | ||
1343 | #endif | ||
1344 | p->pci_ops = &pci_sun4v_ops; | ||
1345 | |||
1346 | /* Like PSYCHO and SCHIZO we have a 2GB aligned area | 1308 | /* Like PSYCHO and SCHIZO we have a 2GB aligned area |
1347 | * for memory space. | 1309 | * for memory space. |
1348 | */ | 1310 | */ |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 3b05428cc909..91f6e2a74ad5 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -1002,24 +1002,24 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) | |||
1002 | u64 control; | 1002 | u64 control; |
1003 | 1003 | ||
1004 | irq = sbus_build_irq(sbus, SYSIO_UE_INO); | 1004 | irq = sbus_build_irq(sbus, SYSIO_UE_INO); |
1005 | if (request_irq(irq, sysio_ue_handler, | 1005 | if (request_irq(irq, sysio_ue_handler, 0, |
1006 | IRQF_SHARED, "SYSIO UE", sbus) < 0) { | 1006 | "SYSIO_UE", sbus) < 0) { |
1007 | prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n", | 1007 | prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n", |
1008 | sbus->portid); | 1008 | sbus->portid); |
1009 | prom_halt(); | 1009 | prom_halt(); |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | irq = sbus_build_irq(sbus, SYSIO_CE_INO); | 1012 | irq = sbus_build_irq(sbus, SYSIO_CE_INO); |
1013 | if (request_irq(irq, sysio_ce_handler, | 1013 | if (request_irq(irq, sysio_ce_handler, 0, |
1014 | IRQF_SHARED, "SYSIO CE", sbus) < 0) { | 1014 | "SYSIO_CE", sbus) < 0) { |
1015 | prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n", | 1015 | prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n", |
1016 | sbus->portid); | 1016 | sbus->portid); |
1017 | prom_halt(); | 1017 | prom_halt(); |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | irq = sbus_build_irq(sbus, SYSIO_SBUSERR_INO); | 1020 | irq = sbus_build_irq(sbus, SYSIO_SBUSERR_INO); |
1021 | if (request_irq(irq, sysio_sbus_error_handler, | 1021 | if (request_irq(irq, sysio_sbus_error_handler, 0, |
1022 | IRQF_SHARED, "SYSIO SBUS Error", sbus) < 0) { | 1022 | "SYSIO_SBERR", sbus) < 0) { |
1023 | prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n", | 1023 | prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n", |
1024 | sbus->portid); | 1024 | sbus->portid); |
1025 | prom_halt(); | 1025 | prom_halt(); |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 692e46a6b8da..abd83129b2e7 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
@@ -793,7 +793,7 @@ asmlinkage long sys32_utimes(char __user *filename, | |||
793 | tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; | 793 | tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; |
794 | } | 794 | } |
795 | 795 | ||
796 | return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL); | 796 | return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0); |
797 | } | 797 | } |
798 | 798 | ||
799 | /* These are here just in case some old sparc32 binary calls it. */ | 799 | /* These are here just in case some old sparc32 binary calls it. */ |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 48c36fe6dc62..5fe7f9ad4a92 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
@@ -81,6 +81,7 @@ sys_call_table32: | |||
81 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare | 81 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare |
82 | /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy | 82 | /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy |
83 | .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait | 83 | .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait |
84 | /*310*/ .word compat_sys_utimensat | ||
84 | 85 | ||
85 | #endif /* CONFIG_COMPAT */ | 86 | #endif /* CONFIG_COMPAT */ |
86 | 87 | ||
@@ -152,6 +153,7 @@ sys_call_table: | |||
152 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 153 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
153 | /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy | 154 | /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy |
154 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 155 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
156 | /*310*/ .word sys_utimensat | ||
155 | 157 | ||
156 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | 158 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ |
157 | defined(CONFIG_SOLARIS_EMUL_MODULE) | 159 | defined(CONFIG_SOLARIS_EMUL_MODULE) |
@@ -269,5 +271,6 @@ sunos_sys_table: | |||
269 | .word sunos_nosys, sunos_nosys, sunos_nosys | 271 | .word sunos_nosys, sunos_nosys, sunos_nosys |
270 | .word sunos_nosys, sunos_nosys, sunos_nosys | 272 | .word sunos_nosys, sunos_nosys, sunos_nosys |
271 | .word sunos_nosys | 273 | .word sunos_nosys |
274 | /*310*/ .long sunos_nosys | ||
272 | 275 | ||
273 | #endif | 276 | #endif |
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index c32e309f7788..b582024d2199 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c | |||
@@ -32,36 +32,23 @@ | |||
32 | #include <asm/mmu_context.h> | 32 | #include <asm/mmu_context.h> |
33 | 33 | ||
34 | #ifdef CONFIG_KPROBES | 34 | #ifdef CONFIG_KPROBES |
35 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | 35 | static inline int notify_page_fault(struct pt_regs *regs) |
36 | |||
37 | /* Hook to register for page fault notifications */ | ||
38 | int register_page_fault_notifier(struct notifier_block *nb) | ||
39 | { | 36 | { |
40 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | 37 | int ret = 0; |
41 | } | 38 | |
42 | 39 | /* kprobe_running() needs smp_processor_id() */ | |
43 | int unregister_page_fault_notifier(struct notifier_block *nb) | 40 | if (!user_mode(regs)) { |
44 | { | 41 | preempt_disable(); |
45 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | 42 | if (kprobe_running() && kprobe_fault_handler(regs, 0)) |
46 | } | 43 | ret = 1; |
47 | 44 | preempt_enable(); | |
48 | static inline int notify_page_fault(enum die_val val, const char *str, | 45 | } |
49 | struct pt_regs *regs, long err, int trap, int sig) | 46 | return ret; |
50 | { | ||
51 | struct die_args args = { | ||
52 | .regs = regs, | ||
53 | .str = str, | ||
54 | .err = err, | ||
55 | .trapnr = trap, | ||
56 | .signr = sig | ||
57 | }; | ||
58 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | ||
59 | } | 47 | } |
60 | #else | 48 | #else |
61 | static inline int notify_page_fault(enum die_val val, const char *str, | 49 | static inline int notify_page_fault(struct pt_regs *regs) |
62 | struct pt_regs *regs, long err, int trap, int sig) | ||
63 | { | 50 | { |
64 | return NOTIFY_DONE; | 51 | return 0; |
65 | } | 52 | } |
66 | #endif | 53 | #endif |
67 | 54 | ||
@@ -120,9 +107,6 @@ static void __kprobes unhandled_fault(unsigned long address, | |||
120 | printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n", | 107 | printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n", |
121 | (tsk->mm ? (unsigned long) tsk->mm->pgd : | 108 | (tsk->mm ? (unsigned long) tsk->mm->pgd : |
122 | (unsigned long) tsk->active_mm->pgd)); | 109 | (unsigned long) tsk->active_mm->pgd)); |
123 | if (notify_die(DIE_GPF, "general protection fault", regs, | ||
124 | 0, 0, SIGSEGV) == NOTIFY_STOP) | ||
125 | return; | ||
126 | die_if_kernel("Oops", regs); | 110 | die_if_kernel("Oops", regs); |
127 | } | 111 | } |
128 | 112 | ||
@@ -299,8 +283,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) | |||
299 | 283 | ||
300 | fault_code = get_thread_fault_code(); | 284 | fault_code = get_thread_fault_code(); |
301 | 285 | ||
302 | if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, | 286 | if (notify_page_fault(regs)) |
303 | fault_code, 0, SIGSEGV) == NOTIFY_STOP) | ||
304 | return; | 287 | return; |
305 | 288 | ||
306 | si_code = SEGV_MAPERR; | 289 | si_code = SEGV_MAPERR; |