diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 32 |
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 | ||
816 | static void psycho_iommu_init(struct pci_pbm_info *pbm) | 816 | static 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 | |||
1076 | fatal_memory_error: | ||
1077 | prom_printf("PSYCHO: Fatal memory allocation error.\n"); | ||
1078 | prom_halt(); | ||
1069 | } | 1079 | } |