summaryrefslogtreecommitdiff
path: root/drivers/vme/bridges/vme_tsi148.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-27 01:46:08 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-27 01:46:08 +0300
commit23908db413eccd77084b09c9b0a4451dfb0524c0 (patch)
tree646f21a92496bdc04175e95642b0ecb2dc3dd09e /drivers/vme/bridges/vme_tsi148.c
parent8d7804a2f03dbd34940fcb426450c730adf29dae (diff)
parent53a20e9e378ecd52f0afa4b60f8f8c81b6f97c27 (diff)
downloadlinux-23908db413eccd77084b09c9b0a4451dfb0524c0.tar.xz
Merge tag 'staging-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH: "Here's the big, really big, staging tree patches for 4.2-rc1. Loads of stuff in here, almost all just coding style fixes / churn, and a few new drivers as well, one of which I just disabled from the build a few minutes ago due to way too many build warnings. Other than the one "disable this driver" patch, all of these have been in linux-next for quite a while with no reported issues" * tag 'staging-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1163 commits) staging: wilc1000: disable driver due to build warnings Staging: rts5208: fix CHANGE_LINK_STATE value Staging: sm750fb: ddk750_swi2c.c: Insert spaces before parenthesis Staging: sm750fb: ddk750_swi2c.c: Place braces on correct lines Staging: sm750fb: ddk750_swi2c.c: Insert spaces around operators Staging: sm750fb: ddk750_swi2c.c: Replace spaces with tabs Staging: sm750fb: ddk750_swi2c.h: Shorten lines to under 80 characters Staging: sm750fb: ddk750_swi2c.h: Replace spaces with tabs Staging: sm750fb: modedb.h: Shorten lines to under 80 characters Staging: sm750fb: modedb.h: Replace spaces with tabs staging: comedi: addi_apci_3120: rename 'this_board' variables staging: comedi: addi_apci_1516: rename 'this_board' variables staging: comedi: ni_atmio: cleanup ni_getboardtype() staging: comedi: vmk80xx: sanity check context used to get the boardinfo staging: comedi: vmk80xx: rename 'boardinfo' variables staging: comedi: dt3000: rename 'this_board' variables staging: comedi: adv_pci_dio: rename 'this_board' variables staging: comedi: cb_pcidas64: rename 'thisboard' variables staging: comedi: cb_pcidas: rename 'thisboard' variables staging: comedi: me4000: rename 'thisboard' variables ...
Diffstat (limited to 'drivers/vme/bridges/vme_tsi148.c')
-rw-r--r--drivers/vme/bridges/vme_tsi148.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 895c2a31918d..fb1e7ad272ec 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -1833,24 +1833,29 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
/* Add to list */
list_add_tail(&entry->list, &list->entries);
+ entry->dma_handle = dma_map_single(tsi148_bridge->parent,
+ &entry->descriptor,
+ sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
+ if (dma_mapping_error(tsi148_bridge->parent, entry->dma_handle)) {
+ dev_err(tsi148_bridge->parent, "DMA mapping error\n");
+ retval = -EINVAL;
+ goto err_dma;
+ }
+
/* Fill out previous descriptors "Next Address" */
if (entry->list.prev != &list->entries) {
- prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
- list);
- /* We need the bus address for the pointer */
- entry->dma_handle = dma_map_single(tsi148_bridge->parent,
- &entry->descriptor,
- sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
-
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);
+ prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
+ list);
+ prev->descriptor.dnlau = cpu_to_be32(address_high);
+ prev->descriptor.dnlal = cpu_to_be32(address_low);
}
return 0;
+err_dma:
err_dest:
err_source:
err_align:
@@ -1887,7 +1892,7 @@ static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
static int tsi148_dma_list_exec(struct vme_dma_list *list)
{
struct vme_dma_resource *ctrlr;
- int channel, retval = 0;
+ int channel, retval;
struct tsi148_dma_entry *entry;
u32 bus_addr_high, bus_addr_low;
u32 val, dctlreg = 0;
@@ -1921,10 +1926,6 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
entry = list_first_entry(&list->entries, struct tsi148_dma_entry,
list);
- entry->dma_handle = dma_map_single(tsi148_bridge->parent,
- &entry->descriptor,
- sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
-
mutex_unlock(&ctrlr->mtx);
reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low);
@@ -1941,9 +1942,19 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
- wait_event_interruptible(bridge->dma_queue[channel],
+ retval = wait_event_interruptible(bridge->dma_queue[channel],
tsi148_dma_busy(ctrlr->parent, channel));
+ if (retval) {
+ iowrite32be(dctlreg | TSI148_LCSR_DCTL_ABT, bridge->base +
+ TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
+ /* Wait for the operation to abort */
+ wait_event(bridge->dma_queue[channel],
+ tsi148_dma_busy(ctrlr->parent, channel));
+ retval = -EINTR;
+ goto exit;
+ }
+
/*
* Read status register, this register is valid until we kick off a
* new transfer.
@@ -1956,6 +1967,7 @@ static int tsi148_dma_list_exec(struct vme_dma_list *list)
retval = -EIO;
}
+exit:
/* Remove list from running list */
mutex_lock(&ctrlr->mtx);
list_del(&list->list);