diff options
Diffstat (limited to 'arch/powerpc/kernel/vio.c')
-rw-r--r-- | arch/powerpc/kernel/vio.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 00b9436..441d2a7 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) * memory in this pool does not change. */ if (spare_needed && reserve_freed) { - tmp = min(spare_needed, min(reserve_freed, - (viodev->cmo.entitled - - VIO_CMO_MIN_ENT))); + tmp = min3(spare_needed, reserve_freed, (viodev->cmo.entitled - VIO_CMO_MIN_ENT)); vio_cmo.spare += tmp; viodev->cmo.entitled -= tmp; @@ -1059,7 +1057,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) if (!dma_window) return NULL; - tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); if (tbl == NULL) return NULL; @@ -1072,6 +1070,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; tbl->it_busno = 0; tbl->it_type = TCE_VB; + tbl->it_blocksize = 16; return iommu_init_table(tbl, -1); } @@ -1183,7 +1182,12 @@ EXPORT_SYMBOL(vio_unregister_driver); /* vio_dev refcount hit 0 */ static void __devinit vio_dev_release(struct device *dev) { - /* XXX should free TCE table */ + struct iommu_table *tbl = get_iommu_table_base(dev); + + /* iSeries uses a common table for all vio devices */ + if (!firmware_has_feature(FW_FEATURE_ISERIES) && tbl) + iommu_free_table(tbl, dev->of_node ? + dev->of_node->full_name : dev_name(dev)); of_node_put(dev->of_node); kfree(to_vio_dev(dev)); } @@ -1253,8 +1257,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) if (device_register(&viodev->dev)) { printk(KERN_ERR "%s: failed to register device %s\n", __func__, dev_name(&viodev->dev)); - /* XXX free TCE table */ - kfree(viodev); + put_device(&viodev->dev); return NULL; } |