|
@@ -47,9 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
|
|
|
|
|
|
#define MAX_BUSES 3
|
|
|
|
|
|
-#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
|
|
|
-#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
|
|
|
-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
|
|
|
+#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
|
|
|
+#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
|
|
|
+#define IS_DMA_ALIGNED(x) (((x) & 0x07) == 0)
|
|
|
+#define MAX_DMA_LEN 8191
|
|
|
|
|
|
/*
|
|
|
* for testing SSCR1 changes that require SSP restart, basically
|
|
@@ -887,14 +888,27 @@ static void pump_transfers(unsigned long data)
|
|
|
drv_data->cs_control(PXA2XX_CS_DEASSERT);
|
|
|
}
|
|
|
|
|
|
- /* Check transfer length */
|
|
|
- if (transfer->len > 8191)
|
|
|
- {
|
|
|
- dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
|
|
|
- "length greater than 8191\n");
|
|
|
- message->status = -EINVAL;
|
|
|
- giveback(drv_data);
|
|
|
- return;
|
|
|
+ /* Check for transfers that need multiple DMA segments */
|
|
|
+ if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
|
|
|
+
|
|
|
+ /* reject already-mapped transfers; PIO won't always work */
|
|
|
+ if (message->is_dma_mapped
|
|
|
+ || transfer->rx_dma || transfer->tx_dma) {
|
|
|
+ dev_err(&drv_data->pdev->dev,
|
|
|
+ "pump_transfers: mapped transfer length "
|
|
|
+ "of %lu is greater than %d\n",
|
|
|
+ transfer->len, MAX_DMA_LEN);
|
|
|
+ message->status = -EINVAL;
|
|
|
+ giveback(drv_data);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* warn ... we force this to PIO mode */
|
|
|
+ if (printk_ratelimit())
|
|
|
+ dev_warn(&message->spi->dev, "pump_transfers: "
|
|
|
+ "DMA disabled for transfer length %ld "
|
|
|
+ "greater than %d\n",
|
|
|
+ (long)drv_data->len, MAX_DMA_LEN);
|
|
|
}
|
|
|
|
|
|
/* Setup the transfer state based on the type of transfer */
|
|
@@ -962,7 +976,7 @@ static void pump_transfers(unsigned long data)
|
|
|
&dma_thresh))
|
|
|
if (printk_ratelimit())
|
|
|
dev_warn(&message->spi->dev,
|
|
|
- "pump_transfer: "
|
|
|
+ "pump_transfers: "
|
|
|
"DMA burst size reduced to "
|
|
|
"match bits_per_word\n");
|
|
|
}
|
|
@@ -976,8 +990,23 @@ static void pump_transfers(unsigned long data)
|
|
|
|
|
|
message->state = RUNNING_STATE;
|
|
|
|
|
|
- /* Try to map dma buffer and do a dma transfer if successful */
|
|
|
- if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
|
|
|
+ /* Try to map dma buffer and do a dma transfer if successful, but
|
|
|
+ * only if the length is non-zero and less than MAX_DMA_LEN.
|
|
|
+ *
|
|
|
+ * Zero-length non-descriptor DMA is illegal on PXA2xx; force use
|
|
|
+ * of PIO instead. Care is needed above because the transfer may
|
|
|
+ * have have been passed with buffers that are already dma mapped.
|
|
|
+ * A zero-length transfer in PIO mode will not try to write/read
|
|
|
+ * to/from the buffers
|
|
|
+ *
|
|
|
+ * REVISIT large transfers are exactly where we most want to be
|
|
|
+ * using DMA. If this happens much, split those transfers into
|
|
|
+ * multiple DMA segments rather than forcing PIO.
|
|
|
+ */
|
|
|
+ drv_data->dma_mapped = 0;
|
|
|
+ if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
|
|
|
+ drv_data->dma_mapped = map_dma_buffers(drv_data);
|
|
|
+ if (drv_data->dma_mapped) {
|
|
|
|
|
|
/* Ensure we have the correct interrupt handler */
|
|
|
drv_data->transfer_handler = dma_transfer;
|