diff options
Diffstat (limited to 'drivers/parisc/sba_iommu.c')
| -rw-r--r-- | drivers/parisc/sba_iommu.c | 63 |
1 files changed, 35 insertions, 28 deletions
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index a70cf16ee1a..e5999c4cedc 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
| @@ -1206,30 +1206,48 @@ sba_alloc_pdir(unsigned int pdir_size) | |||
| 1206 | return (void *) pdir_base; | 1206 | return (void *) pdir_base; |
| 1207 | } | 1207 | } |
| 1208 | 1208 | ||
| 1209 | static struct device *next_device(struct klist_iter *i) | 1209 | struct ibase_data_struct { |
| 1210 | struct ioc *ioc; | ||
| 1211 | int ioc_num; | ||
| 1212 | }; | ||
| 1213 | |||
| 1214 | static int setup_ibase_imask_callback(struct device *dev, void *data) | ||
| 1210 | { | 1215 | { |
| 1211 | struct klist_node * n = klist_next(i); | 1216 | /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ |
| 1212 | return n ? container_of(n, struct device, knode_parent) : NULL; | 1217 | extern void lba_set_iregs(struct parisc_device *, u32, u32); |
| 1218 | struct parisc_device *lba = to_parisc_device(dev); | ||
| 1219 | struct ibase_data_struct *ibd = data; | ||
| 1220 | int rope_num = (lba->hpa.start >> 13) & 0xf; | ||
| 1221 | if (rope_num >> 3 == ibd->ioc_num) | ||
| 1222 | lba_set_iregs(lba, ibd->ioc->ibase, ibd->ioc->imask); | ||
| 1223 | return 0; | ||
| 1213 | } | 1224 | } |
| 1214 | 1225 | ||
| 1215 | /* setup Mercury or Elroy IBASE/IMASK registers. */ | 1226 | /* setup Mercury or Elroy IBASE/IMASK registers. */ |
| 1216 | static void | 1227 | static void |
| 1217 | setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | 1228 | setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) |
| 1218 | { | 1229 | { |
| 1219 | /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ | 1230 | struct ibase_data_struct ibase_data = { |
| 1220 | extern void lba_set_iregs(struct parisc_device *, u32, u32); | 1231 | .ioc = ioc, |
| 1221 | struct device *dev; | 1232 | .ioc_num = ioc_num, |
| 1222 | struct klist_iter i; | 1233 | }; |
| 1223 | 1234 | ||
| 1224 | klist_iter_init(&sba->dev.klist_children, &i); | 1235 | device_for_each_child(&sba->dev, &ibase_data, |
| 1225 | while ((dev = next_device(&i))) { | 1236 | setup_ibase_imask_callback); |
| 1226 | struct parisc_device *lba = to_parisc_device(dev); | 1237 | } |
| 1227 | int rope_num = (lba->hpa.start >> 13) & 0xf; | 1238 | |
| 1228 | if (rope_num >> 3 == ioc_num) | 1239 | #ifdef SBA_AGP_SUPPORT |
| 1229 | lba_set_iregs(lba, ioc->ibase, ioc->imask); | 1240 | static int |
| 1230 | } | 1241 | sba_ioc_find_quicksilver(struct device *dev, void *data) |
| 1231 | klist_iter_exit(&i); | 1242 | { |
| 1243 | int *agp_found = data; | ||
| 1244 | struct parisc_device *lba = to_parisc_device(dev); | ||
| 1245 | |||
| 1246 | if (IS_QUICKSILVER(lba)) | ||
| 1247 | *agp_found = 1; | ||
| 1248 | return 0; | ||
| 1232 | } | 1249 | } |
| 1250 | #endif | ||
| 1233 | 1251 | ||
| 1234 | static void | 1252 | static void |
| 1235 | sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | 1253 | sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) |
| @@ -1332,9 +1350,6 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
| 1332 | WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); | 1350 | WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); |
| 1333 | 1351 | ||
| 1334 | #ifdef SBA_AGP_SUPPORT | 1352 | #ifdef SBA_AGP_SUPPORT |
| 1335 | { | ||
| 1336 | struct klist_iter i; | ||
| 1337 | struct device *dev = NULL; | ||
| 1338 | 1353 | ||
| 1339 | /* | 1354 | /* |
| 1340 | ** If an AGP device is present, only use half of the IOV space | 1355 | ** If an AGP device is present, only use half of the IOV space |
| @@ -1344,13 +1359,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
| 1344 | ** We program the next pdir index after we stop w/ a key for | 1359 | ** We program the next pdir index after we stop w/ a key for |
| 1345 | ** the GART code to handshake on. | 1360 | ** the GART code to handshake on. |
| 1346 | */ | 1361 | */ |
| 1347 | klist_iter_init(&sba->dev.klist_children, &i); | 1362 | device_for_each_child(&sba->dev, &agp_found, sba_ioc_find_quicksilver); |
| 1348 | while ((dev = next_device(&i))) { | ||
| 1349 | struct parisc_device *lba = to_parisc_device(dev); | ||
| 1350 | if (IS_QUICKSILVER(lba)) | ||
| 1351 | agp_found = 1; | ||
| 1352 | } | ||
| 1353 | klist_iter_exit(&i); | ||
| 1354 | 1363 | ||
| 1355 | if (agp_found && sba_reserve_agpgart) { | 1364 | if (agp_found && sba_reserve_agpgart) { |
| 1356 | printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", | 1365 | printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", |
| @@ -1358,9 +1367,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
| 1358 | ioc->pdir_size /= 2; | 1367 | ioc->pdir_size /= 2; |
| 1359 | ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE; | 1368 | ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE; |
| 1360 | } | 1369 | } |
| 1361 | } | ||
| 1362 | #endif /*SBA_AGP_SUPPORT*/ | 1370 | #endif /*SBA_AGP_SUPPORT*/ |
| 1363 | |||
| 1364 | } | 1371 | } |
| 1365 | 1372 | ||
| 1366 | static void | 1373 | static void |
