This returns old TCE values to the caller if requested.
The caller is expectded to call put_page() for them.

Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru>
---
 arch/powerpc/platforms/powernv/pci.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index e002c66..a9165a5 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -575,6 +575,7 @@ static int pnv_tce_build(struct iommu_table *tbl, long 
index, long npages,
        u64 proto_tce;
        __be64 *tcep, *tces;
        u64 rpn;
+       long i;
 
        proto_tce = TCE_PCI_READ; // Read allowed
 
@@ -584,9 +585,13 @@ static int pnv_tce_build(struct iommu_table *tbl, long 
index, long npages,
        tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset;
        rpn = __pa(uaddr) >> tbl->it_page_shift;
 
-       while (npages--)
-               *(tcep++) = cpu_to_be64(proto_tce |
-                               (rpn++ << tbl->it_page_shift));
+       for (i = 0; i < npages; i++) {
+               unsigned long oldtce = xchg(tcep, cpu_to_be64(proto_tce |
+                               (rpn++ << tbl->it_page_shift)));
+               if (old_tces)
+                       old_tces[i] = (unsigned long) __va(oldtce);
+               tcep++;
+       }
 
        pnv_tce_invalidate(tbl, tces, tcep - 1, rm);
 
-- 
2.0.0

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to