aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/vme
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/vme')
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c163
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.h20
2 files changed, 103 insertions, 80 deletions
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index cd3c821eb0a..ced59421302 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -29,6 +29,7 @@
#include <linux/time.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/byteorder/generic.h>
#include "../vme.h"
#include "../vme_bridge.h"
@@ -1415,51 +1416,55 @@ static unsigned int tsi148_master_rmw(struct vme_master_resource *image,
return result;
}
-static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr,
+static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr,
u32 aspace, u32 cycle, u32 dwidth)
{
+ u32 val;
+
+ val = be32_to_cpu(*attr);
+
/* Setup 2eSST speeds */
switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
case VME_2eSST160:
- *attr |= TSI148_LCSR_DSAT_2eSSTM_160;
+ val |= TSI148_LCSR_DSAT_2eSSTM_160;
break;
case VME_2eSST267:
- *attr |= TSI148_LCSR_DSAT_2eSSTM_267;
+ val |= TSI148_LCSR_DSAT_2eSSTM_267;
break;
case VME_2eSST320:
- *attr |= TSI148_LCSR_DSAT_2eSSTM_320;
+ val |= TSI148_LCSR_DSAT_2eSSTM_320;
break;
}
/* Setup cycle types */
if (cycle & VME_SCT)
- *attr |= TSI148_LCSR_DSAT_TM_SCT;
+ val |= TSI148_LCSR_DSAT_TM_SCT;
if (cycle & VME_BLT)
- *attr |= TSI148_LCSR_DSAT_TM_BLT;
+ val |= TSI148_LCSR_DSAT_TM_BLT;
if (cycle & VME_MBLT)
- *attr |= TSI148_LCSR_DSAT_TM_MBLT;
+ val |= TSI148_LCSR_DSAT_TM_MBLT;
if (cycle & VME_2eVME)
- *attr |= TSI148_LCSR_DSAT_TM_2eVME;
+ val |= TSI148_LCSR_DSAT_TM_2eVME;
if (cycle & VME_2eSST)
- *attr |= TSI148_LCSR_DSAT_TM_2eSST;
+ val |= TSI148_LCSR_DSAT_TM_2eSST;
if (cycle & VME_2eSSTB) {
dev_err(dev, "Currently not setting Broadcast Select "
"Registers\n");
- *attr |= TSI148_LCSR_DSAT_TM_2eSSTB;
+ val |= TSI148_LCSR_DSAT_TM_2eSSTB;
}
/* Setup data width */
switch (dwidth) {
case VME_D16:
- *attr |= TSI148_LCSR_DSAT_DBW_16;
+ val |= TSI148_LCSR_DSAT_DBW_16;
break;
case VME_D32:
- *attr |= TSI148_LCSR_DSAT_DBW_32;
+ val |= TSI148_LCSR_DSAT_DBW_32;
break;
default:
dev_err(dev, "Invalid data width\n");
@@ -1469,31 +1474,31 @@ static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr,
/* Setup address space */
switch (aspace) {
case VME_A16:
- *attr |= TSI148_LCSR_DSAT_AMODE_A16;
+ val |= TSI148_LCSR_DSAT_AMODE_A16;
break;
case VME_A24:
- *attr |= TSI148_LCSR_DSAT_AMODE_A24;
+ val |= TSI148_LCSR_DSAT_AMODE_A24;
break;
case VME_A32:
- *attr |= TSI148_LCSR_DSAT_AMODE_A32;
+ val |= TSI148_LCSR_DSAT_AMODE_A32;
break;
case VME_A64:
- *attr |= TSI148_LCSR_DSAT_AMODE_A64;
+ val |= TSI148_LCSR_DSAT_AMODE_A64;
break;
case VME_CRCSR:
- *attr |= TSI148_LCSR_DSAT_AMODE_CRCSR;
+ val |= TSI148_LCSR_DSAT_AMODE_CRCSR;
break;
case VME_USER1:
- *attr |= TSI148_LCSR_DSAT_AMODE_USER1;
+ val |= TSI148_LCSR_DSAT_AMODE_USER1;
break;
case VME_USER2:
- *attr |= TSI148_LCSR_DSAT_AMODE_USER2;
+ val |= TSI148_LCSR_DSAT_AMODE_USER2;
break;
case VME_USER3:
- *attr |= TSI148_LCSR_DSAT_AMODE_USER3;
+ val |= TSI148_LCSR_DSAT_AMODE_USER3;
break;
case VME_USER4:
- *attr |= TSI148_LCSR_DSAT_AMODE_USER4;
+ val |= TSI148_LCSR_DSAT_AMODE_USER4;
break;
default:
dev_err(dev, "Invalid address space\n");
@@ -1502,58 +1507,64 @@ static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr,
}
if (cycle & VME_SUPER)
- *attr |= TSI148_LCSR_DSAT_SUP;
+ val |= TSI148_LCSR_DSAT_SUP;
if (cycle & VME_PROG)
- *attr |= TSI148_LCSR_DSAT_PGM;
+ val |= TSI148_LCSR_DSAT_PGM;
+
+ *attr = cpu_to_be32(val);
return 0;
}
-static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr,
+static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr,
u32 aspace, u32 cycle, u32 dwidth)
{
+ u32 val;
+
+ val = be32_to_cpu(*attr);
+
/* Setup 2eSST speeds */
switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
case VME_2eSST160:
- *attr |= TSI148_LCSR_DDAT_2eSSTM_160;
+ val |= TSI148_LCSR_DDAT_2eSSTM_160;
break;
case VME_2eSST267:
- *attr |= TSI148_LCSR_DDAT_2eSSTM_267;
+ val |= TSI148_LCSR_DDAT_2eSSTM_267;
break;
case VME_2eSST320:
- *attr |= TSI148_LCSR_DDAT_2eSSTM_320;
+ val |= TSI148_LCSR_DDAT_2eSSTM_320;
break;
}
/* Setup cycle types */
if (cycle & VME_SCT)
- *attr |= TSI148_LCSR_DDAT_TM_SCT;
+ val |= TSI148_LCSR_DDAT_TM_SCT;
if (cycle & VME_BLT)
- *attr |= TSI148_LCSR_DDAT_TM_BLT;
+ val |= TSI148_LCSR_DDAT_TM_BLT;
if (cycle & VME_MBLT)
- *attr |= TSI148_LCSR_DDAT_TM_MBLT;
+ val |= TSI148_LCSR_DDAT_TM_MBLT;
if (cycle & VME_2eVME)
- *attr |= TSI148_LCSR_DDAT_TM_2eVME;
+ val |= TSI148_LCSR_DDAT_TM_2eVME;
if (cycle & VME_2eSST)
- *attr |= TSI148_LCSR_DDAT_TM_2eSST;
+ val |= TSI148_LCSR_DDAT_TM_2eSST;
if (cycle & VME_2eSSTB) {
dev_err(dev, "Currently not setting Broadcast Select "
"Registers\n");
- *attr |= TSI148_LCSR_DDAT_TM_2eSSTB;
+ val |= TSI148_LCSR_DDAT_TM_2eSSTB;
}
/* Setup data width */
switch (dwidth) {
case VME_D16:
- *attr |= TSI148_LCSR_DDAT_DBW_16;
+ val |= TSI148_LCSR_DDAT_DBW_16;
break;
case VME_D32:
- *attr |= TSI148_LCSR_DDAT_DBW_32;
+ val |= TSI148_LCSR_DDAT_DBW_32;
break;
default:
dev_err(dev, "Invalid data width\n");
@@ -1563,31 +1574,31 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr,
/* Setup address space */
switch (aspace) {
case VME_A16:
- *attr |= TSI148_LCSR_DDAT_AMODE_A16;
+ val |= TSI148_LCSR_DDAT_AMODE_A16;
break;
case VME_A24:
- *attr |= TSI148_LCSR_DDAT_AMODE_A24;
+ val |= TSI148_LCSR_DDAT_AMODE_A24;
break;
case VME_A32:
- *attr |= TSI148_LCSR_DDAT_AMODE_A32;
+ val |= TSI148_LCSR_DDAT_AMODE_A32;
break;
case VME_A64:
- *attr |= TSI148_LCSR_DDAT_AMODE_A64;
+ val |= TSI148_LCSR_DDAT_AMODE_A64;
break;
case VME_CRCSR:
- *attr |= TSI148_LCSR_DDAT_AMODE_CRCSR;
+ val |= TSI148_LCSR_DDAT_AMODE_CRCSR;
break;
case VME_USER1:
- *attr |= TSI148_LCSR_DDAT_AMODE_USER1;
+ val |= TSI148_LCSR_DDAT_AMODE_USER1;
break;
case VME_USER2:
- *attr |= TSI148_LCSR_DDAT_AMODE_USER2;
+ val |= TSI148_LCSR_DDAT_AMODE_USER2;
break;
case VME_USER3:
- *attr |= TSI148_LCSR_DDAT_AMODE_USER3;
+ val |= TSI148_LCSR_DDAT_AMODE_USER3;
break;
case VME_USER4:
- *attr |= TSI148_LCSR_DDAT_AMODE_USER4;
+ val |= TSI148_LCSR_DDAT_AMODE_USER4;
break;
default:
dev_err(dev, "Invalid address space\n");
@@ -1596,21 +1607,25 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr,
}
if (cycle & VME_SUPER)
- *attr |= TSI148_LCSR_DDAT_SUP;
+ val |= TSI148_LCSR_DDAT_SUP;
if (cycle & VME_PROG)
- *attr |= TSI148_LCSR_DDAT_PGM;
+ val |= TSI148_LCSR_DDAT_PGM;
+
+ *attr = cpu_to_be32(val);
return 0;
}
/*
* Add a link list descriptor to the list
+ *
+ * Note: DMA engine expects the DMA descriptor to be big endian.
*/
static int tsi148_dma_list_add(struct vme_dma_list *list,
struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count)
{
struct tsi148_dma_entry *entry, *prev;
- u32 address_high, address_low;
+ u32 address_high, address_low, val;
struct vme_dma_pattern *pattern_attr;
struct vme_dma_pci *pci_attr;
struct vme_dma_vme *vme_attr;
@@ -1647,34 +1662,36 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
case VME_DMA_PATTERN:
pattern_attr = src->private;
- entry->descriptor.dsal = pattern_attr->pattern;
- entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT;
+ entry->descriptor.dsal = cpu_to_be32(pattern_attr->pattern);
+
+ val = TSI148_LCSR_DSAT_TYP_PAT;
+
/* Default behaviour is 32 bit pattern */
if (pattern_attr->type & VME_DMA_PATTERN_BYTE)
- entry->descriptor.dsat |= TSI148_LCSR_DSAT_PSZ;
+ val |= TSI148_LCSR_DSAT_PSZ;
/* It seems that the default behaviour is to increment */
if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0)
- entry->descriptor.dsat |= TSI148_LCSR_DSAT_NIN;
-
+ val |= TSI148_LCSR_DSAT_NIN;
+ entry->descriptor.dsat = cpu_to_be32(val);
break;
case VME_DMA_PCI:
pci_attr = src->private;
reg_split((unsigned long long)pci_attr->address, &address_high,
&address_low);
- entry->descriptor.dsau = address_high;
- entry->descriptor.dsal = address_low;
- entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PCI;
+ entry->descriptor.dsau = cpu_to_be32(address_high);
+ entry->descriptor.dsal = cpu_to_be32(address_low);
+ entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_PCI);
break;
case VME_DMA_VME:
vme_attr = src->private;
reg_split((unsigned long long)vme_attr->address, &address_high,
&address_low);
- entry->descriptor.dsau = address_high;
- entry->descriptor.dsal = address_low;
- entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME;
+ entry->descriptor.dsau = cpu_to_be32(address_high);
+ entry->descriptor.dsal = cpu_to_be32(address_low);
+ entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_VME);
retval = tsi148_dma_set_vme_src_attributes(
tsi148_bridge->parent, &entry->descriptor.dsat,
@@ -1690,9 +1707,8 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
}
/* Assume last link - this will be over-written by adding another */
- entry->descriptor.dnlau = 0;
- entry->descriptor.dnlal = TSI148_LCSR_DNLAL_LLA;
-
+ entry->descriptor.dnlau = cpu_to_be32(0);
+ entry->descriptor.dnlal = cpu_to_be32(TSI148_LCSR_DNLAL_LLA);
/* Fill out destination part */
switch (dest->type) {
@@ -1701,18 +1717,18 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
reg_split((unsigned long long)pci_attr->address, &address_high,
&address_low);
- entry->descriptor.ddau = address_high;
- entry->descriptor.ddal = address_low;
- entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_PCI;
+ entry->descriptor.ddau = cpu_to_be32(address_high);
+ entry->descriptor.ddal = cpu_to_be32(address_low);
+ entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_PCI);
break;
case VME_DMA_VME:
vme_attr = dest->private;
reg_split((unsigned long long)vme_attr->address, &address_high,
&address_low);
- entry->descriptor.ddau = address_high;
- entry->descriptor.ddal = address_low;
- entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME;
+ entry->descriptor.ddau = cpu_to_be32(address_high);
+ entry->descriptor.ddal = cpu_to_be32(address_low);
+ entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_VME);
retval = tsi148_dma_set_vme_dest_attributes(
tsi148_bridge->parent, &entry->descriptor.ddat,
@@ -1728,7 +1744,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
}
/* Fill out count */
- entry->descriptor.dcnt = (u32)count;
+ entry->descriptor.dcnt = cpu_to_be32((u32)count);
/* Add to list */
list_add_tail(&entry->list, &list->entries);
@@ -1742,8 +1758,11 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
&entry->descriptor,
sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
- reg_split((unsigned long long)entry->dma_handle,
- &prev->descriptor.dnlau, &prev->descriptor.dnlal);
+ reg_split((unsigned long long)entry->dma_handle, &address_high,
+ &address_low);
+ entry->descriptor.dnlau = cpu_to_be32(address_high);
+ entry->descriptor.dnlal = cpu_to_be32(address_low);
+
}
return 0;
@@ -1831,12 +1850,16 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
iowrite32be(bus_addr_low, bridge->base +
TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
+ dctlreg = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
+ TSI148_LCSR_OFFSET_DCTL);
+
/* Start the operation */
iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
wait_event_interruptible(bridge->dma_queue[channel],
tsi148_dma_busy(ctrlr->parent, channel));
+
/*
* Read status register, this register is valid until we kick off a
* new transfer.
diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h
index 00b116087d7..f5ed14382a8 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.h
+++ b/drivers/staging/vme/bridges/vme_tsi148.h
@@ -56,16 +56,16 @@ struct tsi148_driver {
* correctly laid out - It must also be aligned on 64-bit boundaries.
*/
struct tsi148_dma_descriptor {
- u32 dsau; /* Source Address */
- u32 dsal;
- u32 ddau; /* Destination Address */
- u32 ddal;
- u32 dsat; /* Source attributes */
- u32 ddat; /* Destination attributes */
- u32 dnlau; /* Next link address */
- u32 dnlal;
- u32 dcnt; /* Byte count */
- u32 ddbs; /* 2eSST Broadcast select */
+ __be32 dsau; /* Source Address */
+ __be32 dsal;
+ __be32 ddau; /* Destination Address */
+ __be32 ddal;
+ __be32 dsat; /* Source attributes */
+ __be32 ddat; /* Destination attributes */
+ __be32 dnlau; /* Next link address */
+ __be32 dnlal;
+ __be32 dcnt; /* Byte count */
+ __be32 ddbs; /* 2eSST Broadcast select */
};
struct tsi148_dma_entry {