aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce J Beare <bruce.j.beare@intel.com>2015-12-22 00:18:58 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-12-22 00:18:58 +0000
commit2bb54da1b71c760ac5e04f57d7baf28ebdd3b899 (patch)
treebd8ac4511c0699b27bc1ffa4a7c4e53e84078a61
parent6572864f8e571fc38a61ce77afa78b98d1984b3f (diff)
parentf0172aecb54127b4a395a515c733cf7c8a7bbfc0 (diff)
downloadedison-v3.10-2bb54da1b71c760ac5e04f57d7baf28ebdd3b899.tar.gz
Merge "spi: enable sending multiple SPI messages" into edison-3.10
-rw-r--r--arch/x86/platform/intel-mid/device_libs/platform_spidev.c2
-rw-r--r--drivers/spi/intel_mid_ssp_spi.c27
2 files changed, 15 insertions, 14 deletions
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_spidev.c b/arch/x86/platform/intel-mid/device_libs/platform_spidev.c
index 40827d64011..cc7512943a2 100644
--- a/arch/x86/platform/intel-mid/device_libs/platform_spidev.c
+++ b/arch/x86/platform/intel-mid/device_libs/platform_spidev.c
@@ -26,7 +26,7 @@ static struct intel_mid_ssp_spi_chip chip = {
.burst_size = DFLT_FIFO_BURST_SIZE,
.timeout = DFLT_TIMEOUT_VAL,
/* SPI DMA is currently usable on Tangier */
- .dma_enabled = true,
+ .dma_enabled = false,
.cs_control = tng_ssp_spi_cs_control,
.platform_pinmux = tng_ssp_spi_platform_pinmux,
};
diff --git a/drivers/spi/intel_mid_ssp_spi.c b/drivers/spi/intel_mid_ssp_spi.c
index 808e53ade01..0ccffed4af5 100644
--- a/drivers/spi/intel_mid_ssp_spi.c
+++ b/drivers/spi/intel_mid_ssp_spi.c
@@ -695,8 +695,8 @@ void drain_trail(struct ssp_drv_context *sspc)
sspc->len = sspc->len - sspc->len_dma_rx;
sspc->cur_msg->actual_length = sspc->len_dma_rx;
- while ((sspc->tx != sspc->tx_end) ||
- (sspc->rx != sspc->rx_end)) {
+ while ((sspc->tx < sspc->tx_end) ||
+ (sspc->rx < sspc->rx_end)) {
sspc->read(sspc);
sspc->write(sspc);
}
@@ -749,9 +749,6 @@ static void int_transfer_complete(struct ssp_drv_context *sspc)
sspc->cs_control(!sspc->cs_assert);
dev_dbg(dev, "End of transfer. SSSR:%08X\n", read_SSSR(reg));
- msg = sspc->cur_msg;
- if (likely(msg->complete))
- msg->complete(msg->context);
complete(&sspc->msg_done);
}
@@ -980,7 +977,13 @@ static int handle_message(struct ssp_drv_context *sspc)
dma_enabled = chip->dma_enabled;
spin_unlock_irqrestore(&sspc->lock, flags);
+ /* multiple transfers must be serialized and this complete() is needed in order
+ to be able to process the transfers list in a generic way */
+ complete(&sspc->msg_done);
+
list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ wait_for_completion(&sspc->msg_done);
+ INIT_COMPLETION(sspc->msg_done);
/* Check transfer length */
if (unlikely((transfer->len > MAX_SPI_TRANSFER_SIZE) ||
@@ -1184,6 +1187,8 @@ static int handle_message(struct ssp_drv_context *sspc)
/* Do the transfer syncronously */
queue_work(sspc->wq_poll_write, &sspc->poll_write);
poll_transfer((unsigned long)sspc);
+ unmap_dma_buffers(sspc);
+ complete(&sspc->msg_done);
}
if (list_is_last(&transfer->transfer_list, &msg->transfers)
@@ -1194,13 +1199,11 @@ static int handle_message(struct ssp_drv_context *sspc)
} /* end of list_for_each_entry */
+ wait_for_completion(&sspc->msg_done);
+
/* Now we are done with this entire message */
- if ((!dma_enabled) || (normal_enabled)) {
- unmap_dma_buffers(sspc);
- if (likely(msg->complete))
- msg->complete(msg->context);
- complete(&sspc->msg_done);
- }
+ if (likely(msg->complete))
+ msg->complete(msg->context);
return 0;
}
@@ -1222,9 +1225,7 @@ static void pump_messages(struct work_struct *work)
list_del_init(&msg->queue);
sspc->cur_msg = msg;
spin_unlock_irqrestore(&sspc->lock, flags);
- INIT_COMPLETION(sspc->msg_done);
handle_message(sspc);
- wait_for_completion(&sspc->msg_done);
spin_lock_irqsave(&sspc->lock, flags);
sspc->cur_msg = NULL;
}