]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/vme/bridges/vme_ca91cx42.c
VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
[karo-tx-linux.git] / drivers / vme / bridges / vme_ca91cx42.c
index a06edbfa95ca6b894ce1ee01ad6ab10241937e5b..92b5719cd99bed4ad296469e8bfc7b812553ed37 100644 (file)
@@ -869,14 +869,13 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
 
        spin_lock(&image->lock);
 
-       /* The following code handles VME address alignment problem
-        * in order to assure the maximal data width cycle.
-        * We cannot use memcpy_xxx directly here because it
-        * may cut data transfer in 8-bits cycles, thus making
-        * D16 cycle impossible.
-        * From the other hand, the bridge itself assures that
-        * maximal configured data cycle is used and splits it
-        * automatically for non-aligned addresses.
+       /* The following code handles VME address alignment. We cannot use
+        * memcpy_xxx here because it may cut data transfers in to 8-bit
+        * cycles when D16 or D32 cycles are required on the VME bus.
+        * On the other hand, the bridge itself assures that the maximum data
+        * cycle configured for the transfer is used and splits it
+        * automatically for non-aligned addresses, so we don't want the
+        * overhead of needlessly forcing small transfers for the entire cycle.
         */
        if ((uintptr_t)addr & 0x1) {
                *(u8 *)buf = ioread8(addr);
@@ -896,9 +895,9 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
        }
 
        count32 = (count - done) & ~0x3;
-       if (count32 > 0) {
-               memcpy_fromio(buf + done, addr + done, (unsigned int)count);
-               done += count32;
+       while (done < count32) {
+               *(u32 *)(buf + done) = ioread32(addr + done);
+               done += 4;
        }
 
        if ((count - done) & 0x2) {
@@ -930,7 +929,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
        spin_lock(&image->lock);
 
        /* Here we apply for the same strategy we do in master_read
-        * function in order to assure D16 cycle when required.
+        * function in order to assure the correct cycles.
         */
        if ((uintptr_t)addr & 0x1) {
                iowrite8(*(u8 *)buf, addr);
@@ -950,9 +949,9 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
        }
 
        count32 = (count - done) & ~0x3;
-       if (count32 > 0) {
-               memcpy_toio(addr + done, buf + done, count32);
-               done += count32;
+       while (done < count32) {
+               iowrite32(*(u32 *)(buf + done), addr + done);
+               done += 4;
        }
 
        if ((count - done) & 0x2) {