aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-28 01:39:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-30 03:27:34 -0400
commitad7ad57c6127042c411353dddb723765964815db (patch)
tree600484291d9cfa68d54dc9b230f5bd115f495213 /arch/sparc64/kernel/pci_psycho.c
parentc7f439b99efbea74c70a5531f92566db5a6731f2 (diff)
[SPARC64]: Fix conflicts in SBUS/PCI/EBUS/ISA DMA handling.
Fully unify all of the DMA ops so that subordinate bus types to the DMA operation providers (such as ebus, isa, of_device) can work transparently. Basically, we just make sure that for every system device we create, the dev->archdata 'iommu' and 'stc' fields are filled in. Then we have two platform variants of the DMA ops, one for SUN4U which actually programs the real hardware, and one for SUN4V which makes hypervisor calls. This also fixes the crashes in parport_pc on sparc64, reported by Meelis Roos. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r--arch/sparc64/kernel/pci_psycho.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 598393a2df16..b6b4cfea5b5f 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -813,16 +813,19 @@ static void psycho_scan_bus(struct pci_pbm_info *pbm)
813 psycho_register_error_handlers(pbm); 813 psycho_register_error_handlers(pbm);
814} 814}
815 815
816static void psycho_iommu_init(struct pci_pbm_info *pbm) 816static int psycho_iommu_init(struct pci_pbm_info *pbm)
817{ 817{
818 struct iommu *iommu = pbm->iommu; 818 struct iommu *iommu = pbm->iommu;
819 unsigned long i; 819 unsigned long i;
820 u64 control; 820 u64 control;
821 int err;
821 822
822 /* Register addresses. */ 823 /* Register addresses. */
823 iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL; 824 iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
824 iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE; 825 iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
825 iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH; 826 iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
827 iommu->iommu_tags = iommu->iommu_flush + (0xa580UL - 0x0210UL);
828
826 /* PSYCHO's IOMMU lacks ctx flushing. */ 829 /* PSYCHO's IOMMU lacks ctx flushing. */
827 iommu->iommu_ctxflush = 0; 830 iommu->iommu_ctxflush = 0;
828 831
@@ -845,7 +848,9 @@ static void psycho_iommu_init(struct pci_pbm_info *pbm)
845 /* Leave diag mode enabled for full-flushing done 848 /* Leave diag mode enabled for full-flushing done
846 * in pci_iommu.c 849 * in pci_iommu.c
847 */ 850 */
848 pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); 851 err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
852 if (err)
853 return err;
849 854
850 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE, 855 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE,
851 __pa(iommu->page_table)); 856 __pa(iommu->page_table));
@@ -858,6 +863,8 @@ static void psycho_iommu_init(struct pci_pbm_info *pbm)
858 /* If necessary, hook us up for starfire IRQ translations. */ 863 /* If necessary, hook us up for starfire IRQ translations. */
859 if (this_is_starfire) 864 if (this_is_starfire)
860 starfire_hookup(pbm->portid); 865 starfire_hookup(pbm->portid);
866
867 return 0;
861} 868}
862 869
863#define PSYCHO_IRQ_RETRY 0x1a00UL 870#define PSYCHO_IRQ_RETRY 0x1a00UL
@@ -1031,15 +1038,12 @@ void psycho_init(struct device_node *dp, char *model_name)
1031 } 1038 }
1032 1039
1033 p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); 1040 p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
1034 if (!p) { 1041 if (!p)
1035 prom_printf("PSYCHO: Fatal memory allocation error.\n"); 1042 goto fatal_memory_error;
1036 prom_halt();
1037 }
1038 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); 1043 iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
1039 if (!iommu) { 1044 if (!iommu)
1040 prom_printf("PSYCHO: Fatal memory allocation error.\n"); 1045 goto fatal_memory_error;
1041 prom_halt(); 1046
1042 }
1043 p->pbm_A.iommu = p->pbm_B.iommu = iommu; 1047 p->pbm_A.iommu = p->pbm_B.iommu = iommu;
1044 1048
1045 p->pbm_A.portid = upa_portid; 1049 p->pbm_A.portid = upa_portid;
@@ -1062,8 +1066,14 @@ void psycho_init(struct device_node *dp, char *model_name)
1062 1066
1063 psycho_controller_hwinit(&p->pbm_A); 1067 psycho_controller_hwinit(&p->pbm_A);
1064 1068
1065 psycho_iommu_init(&p->pbm_A); 1069 if (psycho_iommu_init(&p->pbm_A))
1070 goto fatal_memory_error;
1066 1071
1067 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); 1072 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
1068 psycho_pbm_init(p, dp, is_pbm_a); 1073 psycho_pbm_init(p, dp, is_pbm_a);
1074 return;
1075
1076fatal_memory_error:
1077 prom_printf("PSYCHO: Fatal memory allocation error.\n");
1078 prom_halt();
1069} 1079}