aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parisc/sba_iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parisc/sba_iommu.c')
-rw-r--r--drivers/parisc/sba_iommu.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index a70cf16ee1ad..e5999c4cedc8 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
1209static struct device *next_device(struct klist_iter *i) 1209struct ibase_data_struct {
1210 struct ioc *ioc;
1211 int ioc_num;
1212};
1213
1214static 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. */
1216static void 1227static void
1217setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) 1228setup_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); 1240static int
1230 } 1241sba_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
1234static void 1252static void
1235sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) 1253sba_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
1366static void 1373static void