aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_fire.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/pci_fire.c')
-rw-r--r--arch/sparc64/kernel/pci_fire.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c
index 7f5d473901c4..14d67fe21ab2 100644
--- a/arch/sparc64/kernel/pci_fire.c
+++ b/arch/sparc64/kernel/pci_fire.c
@@ -39,12 +39,12 @@ static void pci_fire_scan_bus(struct pci_pbm_info *pbm)
39#define FIRE_IOMMU_FLUSH 0x40100UL 39#define FIRE_IOMMU_FLUSH 0x40100UL
40#define FIRE_IOMMU_FLUSHINV 0x40108UL 40#define FIRE_IOMMU_FLUSHINV 0x40108UL
41 41
42static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm) 42static int pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm)
43{ 43{
44 struct iommu *iommu = pbm->iommu; 44 struct iommu *iommu = pbm->iommu;
45 u32 vdma[2], dma_mask; 45 u32 vdma[2], dma_mask;
46 u64 control; 46 u64 control;
47 int tsbsize; 47 int tsbsize, err;
48 48
49 /* No virtual-dma property on these guys, use largest size. */ 49 /* No virtual-dma property on these guys, use largest size. */
50 vdma[0] = 0xc0000000; /* base */ 50 vdma[0] = 0xc0000000; /* base */
@@ -68,7 +68,9 @@ static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm)
68 */ 68 */
69 fire_write(iommu->iommu_flushinv, ~(u64)0); 69 fire_write(iommu->iommu_flushinv, ~(u64)0);
70 70
71 pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); 71 err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
72 if (err)
73 return err;
72 74
73 fire_write(iommu->iommu_tsbbase, __pa(iommu->page_table) | 0x7UL); 75 fire_write(iommu->iommu_tsbbase, __pa(iommu->page_table) | 0x7UL);
74 76
@@ -78,6 +80,8 @@ static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm)
78 0x00000002 /* Bypass enable */ | 80 0x00000002 /* Bypass enable */ |
79 0x00000001 /* Translation enable */); 81 0x00000001 /* Translation enable */);
80 fire_write(iommu->iommu_control, control); 82 fire_write(iommu->iommu_control, control);
83
84 return 0;
81} 85}
82 86
83/* Based at pbm->controller_regs */ 87/* Based at pbm->controller_regs */
@@ -167,8 +171,8 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm)
167 fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); 171 fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0);
168} 172}
169 173
170static void pci_fire_pbm_init(struct pci_controller_info *p, 174static int pci_fire_pbm_init(struct pci_controller_info *p,
171 struct device_node *dp, u32 portid) 175 struct device_node *dp, u32 portid)
172{ 176{
173 const struct linux_prom64_registers *regs; 177 const struct linux_prom64_registers *regs;
174 struct pci_pbm_info *pbm; 178 struct pci_pbm_info *pbm;
@@ -203,7 +207,8 @@ static void pci_fire_pbm_init(struct pci_controller_info *p,
203 pci_get_pbm_props(pbm); 207 pci_get_pbm_props(pbm);
204 208
205 pci_fire_hw_init(pbm); 209 pci_fire_hw_init(pbm);
206 pci_fire_pbm_iommu_init(pbm); 210
211 return pci_fire_pbm_iommu_init(pbm);
207} 212}
208 213
209static inline int portid_compare(u32 x, u32 y) 214static inline int portid_compare(u32 x, u32 y)
@@ -222,7 +227,8 @@ void fire_pci_init(struct device_node *dp, const char *model_name)
222 227
223 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { 228 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
224 if (portid_compare(pbm->portid, portid)) { 229 if (portid_compare(pbm->portid, portid)) {
225 pci_fire_pbm_init(pbm->parent, dp, portid); 230 if (pci_fire_pbm_init(pbm->parent, dp, portid))
231 goto fatal_memory_error;
226 return; 232 return;
227 } 233 }
228 } 234 }
@@ -250,7 +256,9 @@ void fire_pci_init(struct device_node *dp, const char *model_name)
250 */ 256 */
251 pci_memspace_mask = 0x7fffffffUL; 257 pci_memspace_mask = 0x7fffffffUL;
252 258
253 pci_fire_pbm_init(p, dp, portid); 259 if (pci_fire_pbm_init(p, dp, portid))
260 goto fatal_memory_error;
261
254 return; 262 return;
255 263
256fatal_memory_error: 264fatal_memory_error: