Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 109796
b: refs/heads/master
c: 7e96445
h: refs/heads/master
v: v3
  • Loading branch information
Ned Forrester authored and Linus Torvalds committed Sep 13, 2008
1 parent a5e4b80 commit c131a77
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8423597d676615f3dd2d9ab36f59f147086b90b8
refs/heads/master: 7e96445533ac3f4f7964646a202ff3620602fab4
57 changes: 43 additions & 14 deletions trunk/drivers/spi/pxa2xx_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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");
}
Expand All @@ -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;
Expand Down

0 comments on commit c131a77

Please sign in to comment.