aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/vio.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/powerpc/kernel/vio.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/powerpc/kernel/vio.c')
-rw-r--r--arch/powerpc/kernel/vio.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index fa3469ddaef8..1b695fdc362b 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -238,9 +238,7 @@ static inline void vio_cmo_dealloc(struct vio_dev *viodev, size_t size)
238 * memory in this pool does not change. 238 * memory in this pool does not change.
239 */ 239 */
240 if (spare_needed && reserve_freed) { 240 if (spare_needed && reserve_freed) {
241 tmp = min(spare_needed, min(reserve_freed, 241 tmp = min3(spare_needed, reserve_freed, (viodev->cmo.entitled - VIO_CMO_MIN_ENT));
242 (viodev->cmo.entitled -
243 VIO_CMO_MIN_ENT)));
244 242
245 vio_cmo.spare += tmp; 243 vio_cmo.spare += tmp;
246 viodev->cmo.entitled -= tmp; 244 viodev->cmo.entitled -= tmp;
@@ -602,6 +600,11 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
602 vio_cmo_dealloc(viodev, alloc_size); 600 vio_cmo_dealloc(viodev, alloc_size);
603} 601}
604 602
603static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask)
604{
605 return dma_iommu_ops.dma_supported(dev, mask);
606}
607
605struct dma_map_ops vio_dma_mapping_ops = { 608struct dma_map_ops vio_dma_mapping_ops = {
606 .alloc_coherent = vio_dma_iommu_alloc_coherent, 609 .alloc_coherent = vio_dma_iommu_alloc_coherent,
607 .free_coherent = vio_dma_iommu_free_coherent, 610 .free_coherent = vio_dma_iommu_free_coherent,
@@ -609,6 +612,7 @@ struct dma_map_ops vio_dma_mapping_ops = {
609 .unmap_sg = vio_dma_iommu_unmap_sg, 612 .unmap_sg = vio_dma_iommu_unmap_sg,
610 .map_page = vio_dma_iommu_map_page, 613 .map_page = vio_dma_iommu_map_page,
611 .unmap_page = vio_dma_iommu_unmap_page, 614 .unmap_page = vio_dma_iommu_unmap_page,
615 .dma_supported = vio_dma_iommu_dma_supported,
612 616
613}; 617};
614 618
@@ -860,8 +864,7 @@ static void vio_cmo_bus_remove(struct vio_dev *viodev)
860 864
861static void vio_cmo_set_dma_ops(struct vio_dev *viodev) 865static void vio_cmo_set_dma_ops(struct vio_dev *viodev)
862{ 866{
863 vio_dma_mapping_ops.dma_supported = dma_iommu_ops.dma_supported; 867 set_dma_ops(&viodev->dev, &vio_dma_mapping_ops);
864 viodev->dev.archdata.dma_ops = &vio_dma_mapping_ops;
865} 868}
866 869
867/** 870/**
@@ -1184,7 +1187,12 @@ EXPORT_SYMBOL(vio_unregister_driver);
1184/* vio_dev refcount hit 0 */ 1187/* vio_dev refcount hit 0 */
1185static void __devinit vio_dev_release(struct device *dev) 1188static void __devinit vio_dev_release(struct device *dev)
1186{ 1189{
1187 /* XXX should free TCE table */ 1190 struct iommu_table *tbl = get_iommu_table_base(dev);
1191
1192 /* iSeries uses a common table for all vio devices */
1193 if (!firmware_has_feature(FW_FEATURE_ISERIES) && tbl)
1194 iommu_free_table(tbl, dev->of_node ?
1195 dev->of_node->full_name : dev_name(dev));
1188 of_node_put(dev->of_node); 1196 of_node_put(dev->of_node);
1189 kfree(to_vio_dev(dev)); 1197 kfree(to_vio_dev(dev));
1190} 1198}
@@ -1241,7 +1249,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1241 if (firmware_has_feature(FW_FEATURE_CMO)) 1249 if (firmware_has_feature(FW_FEATURE_CMO))
1242 vio_cmo_set_dma_ops(viodev); 1250 vio_cmo_set_dma_ops(viodev);
1243 else 1251 else
1244 viodev->dev.archdata.dma_ops = &dma_iommu_ops; 1252 set_dma_ops(&viodev->dev, &dma_iommu_ops);
1245 set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev)); 1253 set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev));
1246 set_dev_node(&viodev->dev, of_node_to_nid(of_node)); 1254 set_dev_node(&viodev->dev, of_node_to_nid(of_node));
1247 1255
@@ -1249,13 +1257,16 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1249 viodev->dev.parent = &vio_bus_device.dev; 1257 viodev->dev.parent = &vio_bus_device.dev;
1250 viodev->dev.bus = &vio_bus_type; 1258 viodev->dev.bus = &vio_bus_type;
1251 viodev->dev.release = vio_dev_release; 1259 viodev->dev.release = vio_dev_release;
1260 /* needed to ensure proper operation of coherent allocations
1261 * later, in case driver doesn't set it explicitly */
1262 dma_set_mask(&viodev->dev, DMA_BIT_MASK(64));
1263 dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
1252 1264
1253 /* register with generic device framework */ 1265 /* register with generic device framework */
1254 if (device_register(&viodev->dev)) { 1266 if (device_register(&viodev->dev)) {
1255 printk(KERN_ERR "%s: failed to register device %s\n", 1267 printk(KERN_ERR "%s: failed to register device %s\n",
1256 __func__, dev_name(&viodev->dev)); 1268 __func__, dev_name(&viodev->dev));
1257 /* XXX free TCE table */ 1269 put_device(&viodev->dev);
1258 kfree(viodev);
1259 return NULL; 1270 return NULL;
1260 } 1271 }
1261 1272