diff options
Diffstat (limited to 'drivers/spi/atmel_spi.c')
-rw-r--r-- | drivers/spi/atmel_spi.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index c4e04428992d..08711e9202ab 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -341,9 +341,9 @@ static void atmel_spi_next_message(struct spi_master *master) | |||
341 | /* | 341 | /* |
342 | * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma: | 342 | * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma: |
343 | * - The buffer is either valid for CPU access, else NULL | 343 | * - The buffer is either valid for CPU access, else NULL |
344 | * - If the buffer is valid, so is its DMA addresss | 344 | * - If the buffer is valid, so is its DMA address |
345 | * | 345 | * |
346 | * This driver manages the dma addresss unless message->is_dma_mapped. | 346 | * This driver manages the dma address unless message->is_dma_mapped. |
347 | */ | 347 | */ |
348 | static int | 348 | static int |
349 | atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) | 349 | atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) |
@@ -352,8 +352,12 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) | |||
352 | 352 | ||
353 | xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS; | 353 | xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS; |
354 | if (xfer->tx_buf) { | 354 | if (xfer->tx_buf) { |
355 | /* tx_buf is a const void* where we need a void * for the dma | ||
356 | * mapping */ | ||
357 | void *nonconst_tx = (void *)xfer->tx_buf; | ||
358 | |||
355 | xfer->tx_dma = dma_map_single(dev, | 359 | xfer->tx_dma = dma_map_single(dev, |
356 | (void *) xfer->tx_buf, xfer->len, | 360 | nonconst_tx, xfer->len, |
357 | DMA_TO_DEVICE); | 361 | DMA_TO_DEVICE); |
358 | if (dma_mapping_error(dev, xfer->tx_dma)) | 362 | if (dma_mapping_error(dev, xfer->tx_dma)) |
359 | return -ENOMEM; | 363 | return -ENOMEM; |
@@ -654,6 +658,8 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) | |||
654 | struct spi_transfer *xfer; | 658 | struct spi_transfer *xfer; |
655 | unsigned long flags; | 659 | unsigned long flags; |
656 | struct device *controller = spi->master->dev.parent; | 660 | struct device *controller = spi->master->dev.parent; |
661 | u8 bits; | ||
662 | struct atmel_spi_device *asd; | ||
657 | 663 | ||
658 | as = spi_master_get_devdata(spi->master); | 664 | as = spi_master_get_devdata(spi->master); |
659 | 665 | ||
@@ -672,8 +678,18 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) | |||
672 | return -EINVAL; | 678 | return -EINVAL; |
673 | } | 679 | } |
674 | 680 | ||
681 | if (xfer->bits_per_word) { | ||
682 | asd = spi->controller_state; | ||
683 | bits = (asd->csr >> 4) & 0xf; | ||
684 | if (bits != xfer->bits_per_word - 8) { | ||
685 | dev_dbg(&spi->dev, "you can't yet change " | ||
686 | "bits_per_word in transfers\n"); | ||
687 | return -ENOPROTOOPT; | ||
688 | } | ||
689 | } | ||
690 | |||
675 | /* FIXME implement these protocol options!! */ | 691 | /* FIXME implement these protocol options!! */ |
676 | if (xfer->bits_per_word || xfer->speed_hz) { | 692 | if (xfer->speed_hz) { |
677 | dev_dbg(&spi->dev, "no protocol options yet\n"); | 693 | dev_dbg(&spi->dev, "no protocol options yet\n"); |
678 | return -ENOPROTOOPT; | 694 | return -ENOPROTOOPT; |
679 | } | 695 | } |
@@ -919,6 +935,6 @@ static void __exit atmel_spi_exit(void) | |||
919 | module_exit(atmel_spi_exit); | 935 | module_exit(atmel_spi_exit); |
920 | 936 | ||
921 | MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver"); | 937 | MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver"); |
922 | MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); | 938 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
923 | MODULE_LICENSE("GPL"); | 939 | MODULE_LICENSE("GPL"); |
924 | MODULE_ALIAS("platform:atmel_spi"); | 940 | MODULE_ALIAS("platform:atmel_spi"); |