diff options
Diffstat (limited to 'drivers/spi/pxa2xx_spi.c')
-rw-r--r-- | drivers/spi/pxa2xx_spi.c | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index a7b9070e1b46..0e53354c1cfe 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -47,9 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi"); | |||
47 | 47 | ||
48 | #define MAX_BUSES 3 | 48 | #define MAX_BUSES 3 |
49 | 49 | ||
50 | #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) | 50 | #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) |
51 | #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) | 51 | #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) |
52 | #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) | 52 | #define IS_DMA_ALIGNED(x) (((x) & 0x07) == 0) |
53 | #define MAX_DMA_LEN 8191 | ||
53 | 54 | ||
54 | /* | 55 | /* |
55 | * for testing SSCR1 changes that require SSP restart, basically | 56 | * for testing SSCR1 changes that require SSP restart, basically |
@@ -887,14 +888,27 @@ static void pump_transfers(unsigned long data) | |||
887 | drv_data->cs_control(PXA2XX_CS_DEASSERT); | 888 | drv_data->cs_control(PXA2XX_CS_DEASSERT); |
888 | } | 889 | } |
889 | 890 | ||
890 | /* Check transfer length */ | 891 | /* Check for transfers that need multiple DMA segments */ |
891 | if (transfer->len > 8191) | 892 | if (transfer->len > MAX_DMA_LEN && chip->enable_dma) { |
892 | { | 893 | |
893 | dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer " | 894 | /* reject already-mapped transfers; PIO won't always work */ |
894 | "length greater than 8191\n"); | 895 | if (message->is_dma_mapped |
895 | message->status = -EINVAL; | 896 | || transfer->rx_dma || transfer->tx_dma) { |
896 | giveback(drv_data); | 897 | dev_err(&drv_data->pdev->dev, |
897 | return; | 898 | "pump_transfers: mapped transfer length " |
899 | "of %lu is greater than %d\n", | ||
900 | transfer->len, MAX_DMA_LEN); | ||
901 | message->status = -EINVAL; | ||
902 | giveback(drv_data); | ||
903 | return; | ||
904 | } | ||
905 | |||
906 | /* warn ... we force this to PIO mode */ | ||
907 | if (printk_ratelimit()) | ||
908 | dev_warn(&message->spi->dev, "pump_transfers: " | ||
909 | "DMA disabled for transfer length %ld " | ||
910 | "greater than %d\n", | ||
911 | (long)drv_data->len, MAX_DMA_LEN); | ||
898 | } | 912 | } |
899 | 913 | ||
900 | /* Setup the transfer state based on the type of transfer */ | 914 | /* Setup the transfer state based on the type of transfer */ |
@@ -962,7 +976,7 @@ static void pump_transfers(unsigned long data) | |||
962 | &dma_thresh)) | 976 | &dma_thresh)) |
963 | if (printk_ratelimit()) | 977 | if (printk_ratelimit()) |
964 | dev_warn(&message->spi->dev, | 978 | dev_warn(&message->spi->dev, |
965 | "pump_transfer: " | 979 | "pump_transfers: " |
966 | "DMA burst size reduced to " | 980 | "DMA burst size reduced to " |
967 | "match bits_per_word\n"); | 981 | "match bits_per_word\n"); |
968 | } | 982 | } |
@@ -976,8 +990,23 @@ static void pump_transfers(unsigned long data) | |||
976 | 990 | ||
977 | message->state = RUNNING_STATE; | 991 | message->state = RUNNING_STATE; |
978 | 992 | ||
979 | /* Try to map dma buffer and do a dma transfer if successful */ | 993 | /* Try to map dma buffer and do a dma transfer if successful, but |
980 | if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) { | 994 | * only if the length is non-zero and less than MAX_DMA_LEN. |
995 | * | ||
996 | * Zero-length non-descriptor DMA is illegal on PXA2xx; force use | ||
997 | * of PIO instead. Care is needed above because the transfer may | ||
998 | * have have been passed with buffers that are already dma mapped. | ||
999 | * A zero-length transfer in PIO mode will not try to write/read | ||
1000 | * to/from the buffers | ||
1001 | * | ||
1002 | * REVISIT large transfers are exactly where we most want to be | ||
1003 | * using DMA. If this happens much, split those transfers into | ||
1004 | * multiple DMA segments rather than forcing PIO. | ||
1005 | */ | ||
1006 | drv_data->dma_mapped = 0; | ||
1007 | if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN) | ||
1008 | drv_data->dma_mapped = map_dma_buffers(drv_data); | ||
1009 | if (drv_data->dma_mapped) { | ||
981 | 1010 | ||
982 | /* Ensure we have the correct interrupt handler */ | 1011 | /* Ensure we have the correct interrupt handler */ |
983 | drv_data->transfer_handler = dma_transfer; | 1012 | drv_data->transfer_handler = dma_transfer; |