powerpc/iommu: Update the generic code to use dynamic iommu page sizes
This patch updates the generic iommu backend code to use the it_page_shift field to determine the iommu page size instead of using hardcoded values. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:

committed by
Benjamin Herrenschmidt

parent
3a553170d3
commit
d084775738
@@ -518,16 +518,18 @@ static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct vio_dev *viodev = to_vio_dev(dev);
|
||||
struct iommu_table *tbl;
|
||||
dma_addr_t ret = DMA_ERROR_CODE;
|
||||
|
||||
if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE_4K))) {
|
||||
tbl = get_iommu_table_base(dev);
|
||||
if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)))) {
|
||||
atomic_inc(&viodev->cmo.allocs_failed);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dma_iommu_ops.map_page(dev, page, offset, size, direction, attrs);
|
||||
if (unlikely(dma_mapping_error(dev, ret))) {
|
||||
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE_4K));
|
||||
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)));
|
||||
atomic_inc(&viodev->cmo.allocs_failed);
|
||||
}
|
||||
|
||||
@@ -540,10 +542,12 @@ static void vio_dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct vio_dev *viodev = to_vio_dev(dev);
|
||||
struct iommu_table *tbl;
|
||||
|
||||
tbl = get_iommu_table_base(dev);
|
||||
dma_iommu_ops.unmap_page(dev, dma_handle, size, direction, attrs);
|
||||
|
||||
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE_4K));
|
||||
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)));
|
||||
}
|
||||
|
||||
static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
|
||||
@@ -551,12 +555,14 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct vio_dev *viodev = to_vio_dev(dev);
|
||||
struct iommu_table *tbl;
|
||||
struct scatterlist *sgl;
|
||||
int ret, count = 0;
|
||||
size_t alloc_size = 0;
|
||||
|
||||
tbl = get_iommu_table_base(dev);
|
||||
for (sgl = sglist; count < nelems; count++, sgl++)
|
||||
alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE_4K);
|
||||
alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE(tbl));
|
||||
|
||||
if (vio_cmo_alloc(viodev, alloc_size)) {
|
||||
atomic_inc(&viodev->cmo.allocs_failed);
|
||||
@@ -572,7 +578,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
|
||||
}
|
||||
|
||||
for (sgl = sglist, count = 0; count < ret; count++, sgl++)
|
||||
alloc_size -= roundup(sgl->dma_length, IOMMU_PAGE_SIZE_4K);
|
||||
alloc_size -= roundup(sgl->dma_length, IOMMU_PAGE_SIZE(tbl));
|
||||
if (alloc_size)
|
||||
vio_cmo_dealloc(viodev, alloc_size);
|
||||
|
||||
@@ -585,12 +591,14 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct vio_dev *viodev = to_vio_dev(dev);
|
||||
struct iommu_table *tbl;
|
||||
struct scatterlist *sgl;
|
||||
size_t alloc_size = 0;
|
||||
int count = 0;
|
||||
|
||||
tbl = get_iommu_table_base(dev);
|
||||
for (sgl = sglist; count < nelems; count++, sgl++)
|
||||
alloc_size += roundup(sgl->dma_length, IOMMU_PAGE_SIZE_4K);
|
||||
alloc_size += roundup(sgl->dma_length, IOMMU_PAGE_SIZE(tbl));
|
||||
|
||||
dma_iommu_ops.unmap_sg(dev, sglist, nelems, direction, attrs);
|
||||
|
||||
@@ -706,11 +714,14 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev)
|
||||
{
|
||||
struct vio_cmo_dev_entry *dev_ent;
|
||||
struct device *dev = &viodev->dev;
|
||||
struct iommu_table *tbl;
|
||||
struct vio_driver *viodrv = to_vio_driver(dev->driver);
|
||||
unsigned long flags;
|
||||
size_t size;
|
||||
bool dma_capable = false;
|
||||
|
||||
tbl = get_iommu_table_base(dev);
|
||||
|
||||
/* A device requires entitlement if it has a DMA window property */
|
||||
switch (viodev->family) {
|
||||
case VDEVICE:
|
||||
@@ -737,7 +748,7 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev)
|
||||
}
|
||||
|
||||
viodev->cmo.desired =
|
||||
IOMMU_PAGE_ALIGN_4K(viodrv->get_desired_dma(viodev));
|
||||
IOMMU_PAGE_ALIGN(viodrv->get_desired_dma(viodev), tbl);
|
||||
if (viodev->cmo.desired < VIO_CMO_MIN_ENT)
|
||||
viodev->cmo.desired = VIO_CMO_MIN_ENT;
|
||||
size = VIO_CMO_MIN_ENT;
|
||||
|
Reference in New Issue
Block a user