diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/amba-pl022.c | 71 | ||||
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 104 | ||||
-rw-r--r-- | drivers/spi/spi_bitbang.c | 13 | ||||
-rw-r--r-- | drivers/spi/spi_imx.c | 12 | ||||
-rw-r--r-- | drivers/spi/spi_sh_msiof.c | 127 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 12 |
6 files changed, 229 insertions, 110 deletions
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 71a1219a995d..4cd05cc05a55 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -329,15 +329,16 @@ struct vendor_data { | |||
329 | /** | 329 | /** |
330 | * struct pl022 - This is the private SSP driver data structure | 330 | * struct pl022 - This is the private SSP driver data structure |
331 | * @adev: AMBA device model hookup | 331 | * @adev: AMBA device model hookup |
332 | * @vendor: Vendor data for the IP block | 332 | * @vendor: vendor data for the IP block |
333 | * @phybase: The physical memory where the SSP device resides | 333 | * @phybase: the physical memory where the SSP device resides |
334 | * @virtbase: The virtual memory where the SSP is mapped | 334 | * @virtbase: the virtual memory where the SSP is mapped |
335 | * @clk: outgoing clock "SPICLK" for the SPI bus | ||
335 | * @master: SPI framework hookup | 336 | * @master: SPI framework hookup |
336 | * @master_info: controller-specific data from machine setup | 337 | * @master_info: controller-specific data from machine setup |
337 | * @regs: SSP controller register's virtual address | ||
338 | * @pump_messages: Work struct for scheduling work to the workqueue | ||
339 | * @lock: spinlock to syncronise access to driver data | ||
340 | * @workqueue: a workqueue on which any spi_message request is queued | 338 | * @workqueue: a workqueue on which any spi_message request is queued |
339 | * @pump_messages: work struct for scheduling work to the workqueue | ||
340 | * @queue_lock: spinlock to syncronise access to message queue | ||
341 | * @queue: message queue | ||
341 | * @busy: workqueue is busy | 342 | * @busy: workqueue is busy |
342 | * @running: workqueue is running | 343 | * @running: workqueue is running |
343 | * @pump_transfers: Tasklet used in Interrupt Transfer mode | 344 | * @pump_transfers: Tasklet used in Interrupt Transfer mode |
@@ -348,8 +349,14 @@ struct vendor_data { | |||
348 | * @tx_end: end position in TX buffer to be read | 349 | * @tx_end: end position in TX buffer to be read |
349 | * @rx: current position in RX buffer to be written | 350 | * @rx: current position in RX buffer to be written |
350 | * @rx_end: end position in RX buffer to be written | 351 | * @rx_end: end position in RX buffer to be written |
351 | * @readingtype: the type of read currently going on | 352 | * @read: the type of read currently going on |
352 | * @writingtype: the type or write currently going on | 353 | * @write: the type of write currently going on |
354 | * @exp_fifo_level: expected FIFO level | ||
355 | * @dma_rx_channel: optional channel for RX DMA | ||
356 | * @dma_tx_channel: optional channel for TX DMA | ||
357 | * @sgt_rx: scattertable for the RX transfer | ||
358 | * @sgt_tx: scattertable for the TX transfer | ||
359 | * @dummypage: a dummy page used for driving data on the bus with DMA | ||
353 | */ | 360 | */ |
354 | struct pl022 { | 361 | struct pl022 { |
355 | struct amba_device *adev; | 362 | struct amba_device *adev; |
@@ -397,8 +404,8 @@ struct pl022 { | |||
397 | * @cpsr: Value of Clock prescale register | 404 | * @cpsr: Value of Clock prescale register |
398 | * @n_bytes: how many bytes(power of 2) reqd for a given data width of client | 405 | * @n_bytes: how many bytes(power of 2) reqd for a given data width of client |
399 | * @enable_dma: Whether to enable DMA or not | 406 | * @enable_dma: Whether to enable DMA or not |
400 | * @write: function ptr to be used to write when doing xfer for this chip | ||
401 | * @read: function ptr to be used to read when doing xfer for this chip | 407 | * @read: function ptr to be used to read when doing xfer for this chip |
408 | * @write: function ptr to be used to write when doing xfer for this chip | ||
402 | * @cs_control: chip select callback provided by chip | 409 | * @cs_control: chip select callback provided by chip |
403 | * @xfer_type: polling/interrupt/DMA | 410 | * @xfer_type: polling/interrupt/DMA |
404 | * | 411 | * |
@@ -508,9 +515,10 @@ static void giveback(struct pl022 *pl022) | |||
508 | msg->state = NULL; | 515 | msg->state = NULL; |
509 | if (msg->complete) | 516 | if (msg->complete) |
510 | msg->complete(msg->context); | 517 | msg->complete(msg->context); |
511 | /* This message is completed, so let's turn off the clocks! */ | 518 | /* This message is completed, so let's turn off the clocks & power */ |
512 | clk_disable(pl022->clk); | 519 | clk_disable(pl022->clk); |
513 | amba_pclk_disable(pl022->adev); | 520 | amba_pclk_disable(pl022->adev); |
521 | amba_vcore_disable(pl022->adev); | ||
514 | } | 522 | } |
515 | 523 | ||
516 | /** | 524 | /** |
@@ -917,7 +925,6 @@ static int configure_dma(struct pl022 *pl022) | |||
917 | struct dma_chan *txchan = pl022->dma_tx_channel; | 925 | struct dma_chan *txchan = pl022->dma_tx_channel; |
918 | struct dma_async_tx_descriptor *rxdesc; | 926 | struct dma_async_tx_descriptor *rxdesc; |
919 | struct dma_async_tx_descriptor *txdesc; | 927 | struct dma_async_tx_descriptor *txdesc; |
920 | dma_cookie_t cookie; | ||
921 | 928 | ||
922 | /* Check that the channels are available */ | 929 | /* Check that the channels are available */ |
923 | if (!rxchan || !txchan) | 930 | if (!rxchan || !txchan) |
@@ -962,10 +969,8 @@ static int configure_dma(struct pl022 *pl022) | |||
962 | tx_conf.dst_addr_width = rx_conf.src_addr_width; | 969 | tx_conf.dst_addr_width = rx_conf.src_addr_width; |
963 | BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width); | 970 | BUG_ON(rx_conf.src_addr_width != tx_conf.dst_addr_width); |
964 | 971 | ||
965 | rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG, | 972 | dmaengine_slave_config(rxchan, &rx_conf); |
966 | (unsigned long) &rx_conf); | 973 | dmaengine_slave_config(txchan, &tx_conf); |
967 | txchan->device->device_control(txchan, DMA_SLAVE_CONFIG, | ||
968 | (unsigned long) &tx_conf); | ||
969 | 974 | ||
970 | /* Create sglists for the transfers */ | 975 | /* Create sglists for the transfers */ |
971 | pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; | 976 | pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; |
@@ -1018,23 +1023,19 @@ static int configure_dma(struct pl022 *pl022) | |||
1018 | rxdesc->callback_param = pl022; | 1023 | rxdesc->callback_param = pl022; |
1019 | 1024 | ||
1020 | /* Submit and fire RX and TX with TX last so we're ready to read! */ | 1025 | /* Submit and fire RX and TX with TX last so we're ready to read! */ |
1021 | cookie = rxdesc->tx_submit(rxdesc); | 1026 | dmaengine_submit(rxdesc); |
1022 | if (dma_submit_error(cookie)) | 1027 | dmaengine_submit(txdesc); |
1023 | goto err_submit_rx; | 1028 | dma_async_issue_pending(rxchan); |
1024 | cookie = txdesc->tx_submit(txdesc); | 1029 | dma_async_issue_pending(txchan); |
1025 | if (dma_submit_error(cookie)) | ||
1026 | goto err_submit_tx; | ||
1027 | rxchan->device->device_issue_pending(rxchan); | ||
1028 | txchan->device->device_issue_pending(txchan); | ||
1029 | 1030 | ||
1030 | return 0; | 1031 | return 0; |
1031 | 1032 | ||
1032 | err_submit_tx: | 1033 | err_submit_tx: |
1033 | err_submit_rx: | 1034 | err_submit_rx: |
1034 | err_txdesc: | 1035 | err_txdesc: |
1035 | txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0); | 1036 | dmaengine_terminate_all(txchan); |
1036 | err_rxdesc: | 1037 | err_rxdesc: |
1037 | rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0); | 1038 | dmaengine_terminate_all(rxchan); |
1038 | dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, | 1039 | dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, |
1039 | pl022->sgt_tx.nents, DMA_TO_DEVICE); | 1040 | pl022->sgt_tx.nents, DMA_TO_DEVICE); |
1040 | err_tx_sgmap: | 1041 | err_tx_sgmap: |
@@ -1101,8 +1102,8 @@ static void terminate_dma(struct pl022 *pl022) | |||
1101 | struct dma_chan *rxchan = pl022->dma_rx_channel; | 1102 | struct dma_chan *rxchan = pl022->dma_rx_channel; |
1102 | struct dma_chan *txchan = pl022->dma_tx_channel; | 1103 | struct dma_chan *txchan = pl022->dma_tx_channel; |
1103 | 1104 | ||
1104 | rxchan->device->device_control(rxchan, DMA_TERMINATE_ALL, 0); | 1105 | dmaengine_terminate_all(rxchan); |
1105 | txchan->device->device_control(txchan, DMA_TERMINATE_ALL, 0); | 1106 | dmaengine_terminate_all(txchan); |
1106 | unmap_free_dma_scatter(pl022); | 1107 | unmap_free_dma_scatter(pl022); |
1107 | } | 1108 | } |
1108 | 1109 | ||
@@ -1482,9 +1483,11 @@ static void pump_messages(struct work_struct *work) | |||
1482 | /* Setup the SPI using the per chip configuration */ | 1483 | /* Setup the SPI using the per chip configuration */ |
1483 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); | 1484 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
1484 | /* | 1485 | /* |
1485 | * We enable the clocks here, then the clocks will be disabled when | 1486 | * We enable the core voltage and clocks here, then the clocks |
1486 | * giveback() is called in each method (poll/interrupt/DMA) | 1487 | * and core will be disabled when giveback() is called in each method |
1488 | * (poll/interrupt/DMA) | ||
1487 | */ | 1489 | */ |
1490 | amba_vcore_enable(pl022->adev); | ||
1488 | amba_pclk_enable(pl022->adev); | 1491 | amba_pclk_enable(pl022->adev); |
1489 | clk_enable(pl022->clk); | 1492 | clk_enable(pl022->clk); |
1490 | restore_state(pl022); | 1493 | restore_state(pl022); |
@@ -1910,8 +1913,6 @@ static int pl022_setup(struct spi_device *spi) | |||
1910 | && ((pl022->master_info)->enable_dma)) { | 1913 | && ((pl022->master_info)->enable_dma)) { |
1911 | chip->enable_dma = true; | 1914 | chip->enable_dma = true; |
1912 | dev_dbg(&spi->dev, "DMA mode set in controller state\n"); | 1915 | dev_dbg(&spi->dev, "DMA mode set in controller state\n"); |
1913 | if (status < 0) | ||
1914 | goto err_config_params; | ||
1915 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, | 1916 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, |
1916 | SSP_DMACR_MASK_RXDMAE, 0); | 1917 | SSP_DMACR_MASK_RXDMAE, 0); |
1917 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, | 1918 | SSP_WRITE_BITS(chip->dmacr, SSP_DMA_ENABLED, |
@@ -2130,8 +2131,12 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) | |||
2130 | goto err_spi_register; | 2131 | goto err_spi_register; |
2131 | } | 2132 | } |
2132 | dev_dbg(dev, "probe succeded\n"); | 2133 | dev_dbg(dev, "probe succeded\n"); |
2133 | /* Disable the silicon block pclk and clock it when needed */ | 2134 | /* |
2135 | * Disable the silicon block pclk and any voltage domain and just | ||
2136 | * power it up and clock it when it's needed | ||
2137 | */ | ||
2134 | amba_pclk_disable(adev); | 2138 | amba_pclk_disable(adev); |
2139 | amba_vcore_disable(adev); | ||
2135 | return 0; | 2140 | return 0; |
2136 | 2141 | ||
2137 | err_spi_register: | 2142 | err_spi_register: |
@@ -2196,9 +2201,11 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state) | |||
2196 | return status; | 2201 | return status; |
2197 | } | 2202 | } |
2198 | 2203 | ||
2204 | amba_vcore_enable(adev); | ||
2199 | amba_pclk_enable(adev); | 2205 | amba_pclk_enable(adev); |
2200 | load_ssp_default_config(pl022); | 2206 | load_ssp_default_config(pl022); |
2201 | amba_pclk_disable(adev); | 2207 | amba_pclk_disable(adev); |
2208 | amba_vcore_disable(adev); | ||
2202 | dev_dbg(&adev->dev, "suspended\n"); | 2209 | dev_dbg(&adev->dev, "suspended\n"); |
2203 | return 0; | 2210 | return 0; |
2204 | } | 2211 | } |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 3f223511127b..a28462486df8 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -425,6 +425,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) | |||
425 | struct bfin_spi_slave_data *chip = drv_data->cur_chip; | 425 | struct bfin_spi_slave_data *chip = drv_data->cur_chip; |
426 | struct spi_message *msg = drv_data->cur_msg; | 426 | struct spi_message *msg = drv_data->cur_msg; |
427 | int n_bytes = drv_data->n_bytes; | 427 | int n_bytes = drv_data->n_bytes; |
428 | int loop = 0; | ||
428 | 429 | ||
429 | /* wait until transfer finished. */ | 430 | /* wait until transfer finished. */ |
430 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 431 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
@@ -435,10 +436,15 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) | |||
435 | /* last read */ | 436 | /* last read */ |
436 | if (drv_data->rx) { | 437 | if (drv_data->rx) { |
437 | dev_dbg(&drv_data->pdev->dev, "last read\n"); | 438 | dev_dbg(&drv_data->pdev->dev, "last read\n"); |
438 | if (n_bytes == 2) | 439 | if (n_bytes % 2) { |
439 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 440 | u16 *buf = (u16 *)drv_data->rx; |
440 | else if (n_bytes == 1) | 441 | for (loop = 0; loop < n_bytes / 2; loop++) |
441 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 442 | *buf++ = read_RDBR(drv_data); |
443 | } else { | ||
444 | u8 *buf = (u8 *)drv_data->rx; | ||
445 | for (loop = 0; loop < n_bytes; loop++) | ||
446 | *buf++ = read_RDBR(drv_data); | ||
447 | } | ||
442 | drv_data->rx += n_bytes; | 448 | drv_data->rx += n_bytes; |
443 | } | 449 | } |
444 | 450 | ||
@@ -458,29 +464,53 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) | |||
458 | if (drv_data->rx && drv_data->tx) { | 464 | if (drv_data->rx && drv_data->tx) { |
459 | /* duplex */ | 465 | /* duplex */ |
460 | dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); | 466 | dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); |
461 | if (drv_data->n_bytes == 2) { | 467 | if (n_bytes % 2) { |
462 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 468 | u16 *buf = (u16 *)drv_data->rx; |
463 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 469 | u16 *buf2 = (u16 *)drv_data->tx; |
464 | } else if (drv_data->n_bytes == 1) { | 470 | for (loop = 0; loop < n_bytes / 2; loop++) { |
465 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 471 | *buf++ = read_RDBR(drv_data); |
466 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 472 | write_TDBR(drv_data, *buf2++); |
473 | } | ||
474 | } else { | ||
475 | u8 *buf = (u8 *)drv_data->rx; | ||
476 | u8 *buf2 = (u8 *)drv_data->tx; | ||
477 | for (loop = 0; loop < n_bytes; loop++) { | ||
478 | *buf++ = read_RDBR(drv_data); | ||
479 | write_TDBR(drv_data, *buf2++); | ||
480 | } | ||
467 | } | 481 | } |
468 | } else if (drv_data->rx) { | 482 | } else if (drv_data->rx) { |
469 | /* read */ | 483 | /* read */ |
470 | dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); | 484 | dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); |
471 | if (drv_data->n_bytes == 2) | 485 | if (n_bytes % 2) { |
472 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 486 | u16 *buf = (u16 *)drv_data->rx; |
473 | else if (drv_data->n_bytes == 1) | 487 | for (loop = 0; loop < n_bytes / 2; loop++) { |
474 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 488 | *buf++ = read_RDBR(drv_data); |
475 | write_TDBR(drv_data, chip->idle_tx_val); | 489 | write_TDBR(drv_data, chip->idle_tx_val); |
490 | } | ||
491 | } else { | ||
492 | u8 *buf = (u8 *)drv_data->rx; | ||
493 | for (loop = 0; loop < n_bytes; loop++) { | ||
494 | *buf++ = read_RDBR(drv_data); | ||
495 | write_TDBR(drv_data, chip->idle_tx_val); | ||
496 | } | ||
497 | } | ||
476 | } else if (drv_data->tx) { | 498 | } else if (drv_data->tx) { |
477 | /* write */ | 499 | /* write */ |
478 | dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); | 500 | dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); |
479 | bfin_spi_dummy_read(drv_data); | 501 | if (n_bytes % 2) { |
480 | if (drv_data->n_bytes == 2) | 502 | u16 *buf = (u16 *)drv_data->tx; |
481 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 503 | for (loop = 0; loop < n_bytes / 2; loop++) { |
482 | else if (drv_data->n_bytes == 1) | 504 | read_RDBR(drv_data); |
483 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 505 | write_TDBR(drv_data, *buf++); |
506 | } | ||
507 | } else { | ||
508 | u8 *buf = (u8 *)drv_data->tx; | ||
509 | for (loop = 0; loop < n_bytes; loop++) { | ||
510 | read_RDBR(drv_data); | ||
511 | write_TDBR(drv_data, *buf++); | ||
512 | } | ||
513 | } | ||
484 | } | 514 | } |
485 | 515 | ||
486 | if (drv_data->tx) | 516 | if (drv_data->tx) |
@@ -623,6 +653,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
623 | message->state = bfin_spi_next_transfer(drv_data); | 653 | message->state = bfin_spi_next_transfer(drv_data); |
624 | /* Schedule next transfer tasklet */ | 654 | /* Schedule next transfer tasklet */ |
625 | tasklet_schedule(&drv_data->pump_transfers); | 655 | tasklet_schedule(&drv_data->pump_transfers); |
656 | return; | ||
626 | } | 657 | } |
627 | 658 | ||
628 | if (transfer->tx_buf != NULL) { | 659 | if (transfer->tx_buf != NULL) { |
@@ -651,16 +682,16 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
651 | 682 | ||
652 | /* Bits per word setup */ | 683 | /* Bits per word setup */ |
653 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; | 684 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; |
654 | if (bits_per_word == 8) { | 685 | if ((bits_per_word > 0) && (bits_per_word % 16 == 0)) { |
655 | drv_data->n_bytes = 1; | 686 | drv_data->n_bytes = bits_per_word/8; |
656 | drv_data->len = transfer->len; | ||
657 | cr_width = 0; | ||
658 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u8; | ||
659 | } else if (bits_per_word == 16) { | ||
660 | drv_data->n_bytes = 2; | ||
661 | drv_data->len = (transfer->len) >> 1; | 687 | drv_data->len = (transfer->len) >> 1; |
662 | cr_width = BIT_CTL_WORDSIZE; | 688 | cr_width = BIT_CTL_WORDSIZE; |
663 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u16; | 689 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u16; |
690 | } else if ((bits_per_word > 0) && (bits_per_word % 8 == 0)) { | ||
691 | drv_data->n_bytes = bits_per_word/8; | ||
692 | drv_data->len = transfer->len; | ||
693 | cr_width = 0; | ||
694 | drv_data->ops = &bfin_bfin_spi_transfer_ops_u8; | ||
664 | } else { | 695 | } else { |
665 | dev_err(&drv_data->pdev->dev, "transfer: unsupported bits_per_word\n"); | 696 | dev_err(&drv_data->pdev->dev, "transfer: unsupported bits_per_word\n"); |
666 | message->status = -EINVAL; | 697 | message->status = -EINVAL; |
@@ -815,10 +846,19 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
815 | if (drv_data->tx == NULL) | 846 | if (drv_data->tx == NULL) |
816 | write_TDBR(drv_data, chip->idle_tx_val); | 847 | write_TDBR(drv_data, chip->idle_tx_val); |
817 | else { | 848 | else { |
818 | if (bits_per_word == 8) | 849 | int loop; |
819 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 850 | if (bits_per_word % 16 == 0) { |
820 | else | 851 | u16 *buf = (u16 *)drv_data->tx; |
821 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 852 | for (loop = 0; loop < bits_per_word / 16; |
853 | loop++) { | ||
854 | write_TDBR(drv_data, *buf++); | ||
855 | } | ||
856 | } else if (bits_per_word % 8 == 0) { | ||
857 | u8 *buf = (u8 *)drv_data->tx; | ||
858 | for (loop = 0; loop < bits_per_word / 8; loop++) | ||
859 | write_TDBR(drv_data, *buf++); | ||
860 | } | ||
861 | |||
822 | drv_data->tx += drv_data->n_bytes; | 862 | drv_data->tx += drv_data->n_bytes; |
823 | } | 863 | } |
824 | 864 | ||
@@ -1031,7 +1071,7 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
1031 | chip->ctl_reg &= bfin_ctl_reg; | 1071 | chip->ctl_reg &= bfin_ctl_reg; |
1032 | } | 1072 | } |
1033 | 1073 | ||
1034 | if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { | 1074 | if (spi->bits_per_word % 8) { |
1035 | dev_err(&spi->dev, "%d bits_per_word is not supported\n", | 1075 | dev_err(&spi->dev, "%d bits_per_word is not supported\n", |
1036 | spi->bits_per_word); | 1076 | spi->bits_per_word); |
1037 | goto error; | 1077 | goto error; |
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 8b55724d5f39..14a63f6010d1 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c | |||
@@ -259,10 +259,6 @@ static void bitbang_work(struct work_struct *work) | |||
259 | struct spi_bitbang *bitbang = | 259 | struct spi_bitbang *bitbang = |
260 | container_of(work, struct spi_bitbang, work); | 260 | container_of(work, struct spi_bitbang, work); |
261 | unsigned long flags; | 261 | unsigned long flags; |
262 | int (*setup_transfer)(struct spi_device *, | ||
263 | struct spi_transfer *); | ||
264 | |||
265 | setup_transfer = bitbang->setup_transfer; | ||
266 | 262 | ||
267 | spin_lock_irqsave(&bitbang->lock, flags); | 263 | spin_lock_irqsave(&bitbang->lock, flags); |
268 | bitbang->busy = 1; | 264 | bitbang->busy = 1; |
@@ -300,11 +296,7 @@ static void bitbang_work(struct work_struct *work) | |||
300 | 296 | ||
301 | /* init (-1) or override (1) transfer params */ | 297 | /* init (-1) or override (1) transfer params */ |
302 | if (do_setup != 0) { | 298 | if (do_setup != 0) { |
303 | if (!setup_transfer) { | 299 | status = bitbang->setup_transfer(spi, t); |
304 | status = -ENOPROTOOPT; | ||
305 | break; | ||
306 | } | ||
307 | status = setup_transfer(spi, t); | ||
308 | if (status < 0) | 300 | if (status < 0) |
309 | break; | 301 | break; |
310 | if (do_setup == -1) | 302 | if (do_setup == -1) |
@@ -465,6 +457,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
465 | } | 457 | } |
466 | } else if (!bitbang->master->setup) | 458 | } else if (!bitbang->master->setup) |
467 | return -EINVAL; | 459 | return -EINVAL; |
460 | if (bitbang->master->transfer == spi_bitbang_transfer && | ||
461 | !bitbang->setup_transfer) | ||
462 | return -EINVAL; | ||
468 | 463 | ||
469 | /* this task is the only thing to touch the SPI bits */ | 464 | /* this task is the only thing to touch the SPI bits */ |
470 | bitbang->busy = 0; | 465 | bitbang->busy = 0; |
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 1cf9d5faabf4..69d6dba67c19 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -174,7 +174,7 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, | |||
174 | #define SPI_IMX2_3_CTRL 0x08 | 174 | #define SPI_IMX2_3_CTRL 0x08 |
175 | #define SPI_IMX2_3_CTRL_ENABLE (1 << 0) | 175 | #define SPI_IMX2_3_CTRL_ENABLE (1 << 0) |
176 | #define SPI_IMX2_3_CTRL_XCH (1 << 2) | 176 | #define SPI_IMX2_3_CTRL_XCH (1 << 2) |
177 | #define SPI_IMX2_3_CTRL_MODE(cs) (1 << ((cs) + 4)) | 177 | #define SPI_IMX2_3_CTRL_MODE_MASK (0xf << 4) |
178 | #define SPI_IMX2_3_CTRL_POSTDIV_OFFSET 8 | 178 | #define SPI_IMX2_3_CTRL_POSTDIV_OFFSET 8 |
179 | #define SPI_IMX2_3_CTRL_PREDIV_OFFSET 12 | 179 | #define SPI_IMX2_3_CTRL_PREDIV_OFFSET 12 |
180 | #define SPI_IMX2_3_CTRL_CS(cs) ((cs) << 18) | 180 | #define SPI_IMX2_3_CTRL_CS(cs) ((cs) << 18) |
@@ -253,8 +253,14 @@ static int __maybe_unused spi_imx2_3_config(struct spi_imx_data *spi_imx, | |||
253 | { | 253 | { |
254 | u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0; | 254 | u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0; |
255 | 255 | ||
256 | /* set master mode */ | 256 | /* |
257 | ctrl |= SPI_IMX2_3_CTRL_MODE(config->cs); | 257 | * The hardware seems to have a race condition when changing modes. The |
258 | * current assumption is that the selection of the channel arrives | ||
259 | * earlier in the hardware than the mode bits when they are written at | ||
260 | * the same time. | ||
261 | * So set master mode for all channels as we do not support slave mode. | ||
262 | */ | ||
263 | ctrl |= SPI_IMX2_3_CTRL_MODE_MASK; | ||
258 | 264 | ||
259 | /* set clock speed */ | 265 | /* set clock speed */ |
260 | ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz); | 266 | ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz); |
diff --git a/drivers/spi/spi_sh_msiof.c b/drivers/spi/spi_sh_msiof.c index 56f60c8ea0ab..da6e42ec856e 100644 --- a/drivers/spi/spi_sh_msiof.c +++ b/drivers/spi/spi_sh_msiof.c | |||
@@ -9,22 +9,22 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/bitmap.h> |
13 | #include <linux/init.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/completion.h> | ||
14 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/err.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/io.h> | ||
21 | #include <linux/kernel.h> | ||
16 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
17 | #include <linux/completion.h> | ||
18 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
19 | #include <linux/gpio.h> | ||
20 | #include <linux/bitmap.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/err.h> | ||
24 | 24 | ||
25 | #include <linux/spi/sh_msiof.h> | ||
25 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
26 | #include <linux/spi/spi_bitbang.h> | 27 | #include <linux/spi/spi_bitbang.h> |
27 | #include <linux/spi/sh_msiof.h> | ||
28 | 28 | ||
29 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
30 | 30 | ||
@@ -67,7 +67,7 @@ struct sh_msiof_spi_priv { | |||
67 | #define STR_TEOF (1 << 23) | 67 | #define STR_TEOF (1 << 23) |
68 | #define STR_REOF (1 << 7) | 68 | #define STR_REOF (1 << 7) |
69 | 69 | ||
70 | static unsigned long sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) | 70 | static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) |
71 | { | 71 | { |
72 | switch (reg_offs) { | 72 | switch (reg_offs) { |
73 | case TSCR: | 73 | case TSCR: |
@@ -79,7 +79,7 @@ static unsigned long sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs, | 81 | static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs, |
82 | unsigned long value) | 82 | u32 value) |
83 | { | 83 | { |
84 | switch (reg_offs) { | 84 | switch (reg_offs) { |
85 | case TSCR: | 85 | case TSCR: |
@@ -93,10 +93,10 @@ static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs, | |||
93 | } | 93 | } |
94 | 94 | ||
95 | static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p, | 95 | static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p, |
96 | unsigned long clr, unsigned long set) | 96 | u32 clr, u32 set) |
97 | { | 97 | { |
98 | unsigned long mask = clr | set; | 98 | u32 mask = clr | set; |
99 | unsigned long data; | 99 | u32 data; |
100 | int k; | 100 | int k; |
101 | 101 | ||
102 | data = sh_msiof_read(p, CTR); | 102 | data = sh_msiof_read(p, CTR); |
@@ -166,10 +166,10 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, | |||
166 | } | 166 | } |
167 | 167 | ||
168 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | 168 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, |
169 | int cpol, int cpha, | 169 | u32 cpol, u32 cpha, |
170 | int tx_hi_z, int lsb_first) | 170 | u32 tx_hi_z, u32 lsb_first) |
171 | { | 171 | { |
172 | unsigned long tmp; | 172 | u32 tmp; |
173 | int edge; | 173 | int edge; |
174 | 174 | ||
175 | /* | 175 | /* |
@@ -187,7 +187,7 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | |||
187 | tmp |= cpol << 30; /* TSCKIZ */ | 187 | tmp |= cpol << 30; /* TSCKIZ */ |
188 | tmp |= cpol << 28; /* RSCKIZ */ | 188 | tmp |= cpol << 28; /* RSCKIZ */ |
189 | 189 | ||
190 | edge = cpol ? cpha : !cpha; | 190 | edge = cpol ^ !cpha; |
191 | 191 | ||
192 | tmp |= edge << 27; /* TEDG */ | 192 | tmp |= edge << 27; /* TEDG */ |
193 | tmp |= edge << 26; /* REDG */ | 193 | tmp |= edge << 26; /* REDG */ |
@@ -197,11 +197,9 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, | |||
197 | 197 | ||
198 | static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p, | 198 | static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p, |
199 | const void *tx_buf, void *rx_buf, | 199 | const void *tx_buf, void *rx_buf, |
200 | int bits, int words) | 200 | u32 bits, u32 words) |
201 | { | 201 | { |
202 | unsigned long dr2; | 202 | u32 dr2 = ((bits - 1) << 24) | ((words - 1) << 16); |
203 | |||
204 | dr2 = ((bits - 1) << 24) | ((words - 1) << 16); | ||
205 | 203 | ||
206 | if (tx_buf) | 204 | if (tx_buf) |
207 | sh_msiof_write(p, TMDR2, dr2); | 205 | sh_msiof_write(p, TMDR2, dr2); |
@@ -222,7 +220,7 @@ static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p) | |||
222 | static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, | 220 | static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, |
223 | const void *tx_buf, int words, int fs) | 221 | const void *tx_buf, int words, int fs) |
224 | { | 222 | { |
225 | const unsigned char *buf_8 = tx_buf; | 223 | const u8 *buf_8 = tx_buf; |
226 | int k; | 224 | int k; |
227 | 225 | ||
228 | for (k = 0; k < words; k++) | 226 | for (k = 0; k < words; k++) |
@@ -232,7 +230,7 @@ static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, | |||
232 | static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p, | 230 | static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p, |
233 | const void *tx_buf, int words, int fs) | 231 | const void *tx_buf, int words, int fs) |
234 | { | 232 | { |
235 | const unsigned short *buf_16 = tx_buf; | 233 | const u16 *buf_16 = tx_buf; |
236 | int k; | 234 | int k; |
237 | 235 | ||
238 | for (k = 0; k < words; k++) | 236 | for (k = 0; k < words; k++) |
@@ -242,7 +240,7 @@ static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p, | |||
242 | static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p, | 240 | static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p, |
243 | const void *tx_buf, int words, int fs) | 241 | const void *tx_buf, int words, int fs) |
244 | { | 242 | { |
245 | const unsigned short *buf_16 = tx_buf; | 243 | const u16 *buf_16 = tx_buf; |
246 | int k; | 244 | int k; |
247 | 245 | ||
248 | for (k = 0; k < words; k++) | 246 | for (k = 0; k < words; k++) |
@@ -252,7 +250,7 @@ static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p, | |||
252 | static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p, | 250 | static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p, |
253 | const void *tx_buf, int words, int fs) | 251 | const void *tx_buf, int words, int fs) |
254 | { | 252 | { |
255 | const unsigned int *buf_32 = tx_buf; | 253 | const u32 *buf_32 = tx_buf; |
256 | int k; | 254 | int k; |
257 | 255 | ||
258 | for (k = 0; k < words; k++) | 256 | for (k = 0; k < words; k++) |
@@ -262,17 +260,37 @@ static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p, | |||
262 | static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p, | 260 | static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p, |
263 | const void *tx_buf, int words, int fs) | 261 | const void *tx_buf, int words, int fs) |
264 | { | 262 | { |
265 | const unsigned int *buf_32 = tx_buf; | 263 | const u32 *buf_32 = tx_buf; |
266 | int k; | 264 | int k; |
267 | 265 | ||
268 | for (k = 0; k < words; k++) | 266 | for (k = 0; k < words; k++) |
269 | sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs); | 267 | sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs); |
270 | } | 268 | } |
271 | 269 | ||
270 | static void sh_msiof_spi_write_fifo_s32(struct sh_msiof_spi_priv *p, | ||
271 | const void *tx_buf, int words, int fs) | ||
272 | { | ||
273 | const u32 *buf_32 = tx_buf; | ||
274 | int k; | ||
275 | |||
276 | for (k = 0; k < words; k++) | ||
277 | sh_msiof_write(p, TFDR, swab32(buf_32[k] << fs)); | ||
278 | } | ||
279 | |||
280 | static void sh_msiof_spi_write_fifo_s32u(struct sh_msiof_spi_priv *p, | ||
281 | const void *tx_buf, int words, int fs) | ||
282 | { | ||
283 | const u32 *buf_32 = tx_buf; | ||
284 | int k; | ||
285 | |||
286 | for (k = 0; k < words; k++) | ||
287 | sh_msiof_write(p, TFDR, swab32(get_unaligned(&buf_32[k]) << fs)); | ||
288 | } | ||
289 | |||
272 | static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, | 290 | static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, |
273 | void *rx_buf, int words, int fs) | 291 | void *rx_buf, int words, int fs) |
274 | { | 292 | { |
275 | unsigned char *buf_8 = rx_buf; | 293 | u8 *buf_8 = rx_buf; |
276 | int k; | 294 | int k; |
277 | 295 | ||
278 | for (k = 0; k < words; k++) | 296 | for (k = 0; k < words; k++) |
@@ -282,7 +300,7 @@ static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p, | |||
282 | static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p, | 300 | static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p, |
283 | void *rx_buf, int words, int fs) | 301 | void *rx_buf, int words, int fs) |
284 | { | 302 | { |
285 | unsigned short *buf_16 = rx_buf; | 303 | u16 *buf_16 = rx_buf; |
286 | int k; | 304 | int k; |
287 | 305 | ||
288 | for (k = 0; k < words; k++) | 306 | for (k = 0; k < words; k++) |
@@ -292,7 +310,7 @@ static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p, | |||
292 | static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p, | 310 | static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p, |
293 | void *rx_buf, int words, int fs) | 311 | void *rx_buf, int words, int fs) |
294 | { | 312 | { |
295 | unsigned short *buf_16 = rx_buf; | 313 | u16 *buf_16 = rx_buf; |
296 | int k; | 314 | int k; |
297 | 315 | ||
298 | for (k = 0; k < words; k++) | 316 | for (k = 0; k < words; k++) |
@@ -302,7 +320,7 @@ static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p, | |||
302 | static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p, | 320 | static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p, |
303 | void *rx_buf, int words, int fs) | 321 | void *rx_buf, int words, int fs) |
304 | { | 322 | { |
305 | unsigned int *buf_32 = rx_buf; | 323 | u32 *buf_32 = rx_buf; |
306 | int k; | 324 | int k; |
307 | 325 | ||
308 | for (k = 0; k < words; k++) | 326 | for (k = 0; k < words; k++) |
@@ -312,19 +330,40 @@ static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p, | |||
312 | static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p, | 330 | static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p, |
313 | void *rx_buf, int words, int fs) | 331 | void *rx_buf, int words, int fs) |
314 | { | 332 | { |
315 | unsigned int *buf_32 = rx_buf; | 333 | u32 *buf_32 = rx_buf; |
316 | int k; | 334 | int k; |
317 | 335 | ||
318 | for (k = 0; k < words; k++) | 336 | for (k = 0; k < words; k++) |
319 | put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]); | 337 | put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]); |
320 | } | 338 | } |
321 | 339 | ||
340 | static void sh_msiof_spi_read_fifo_s32(struct sh_msiof_spi_priv *p, | ||
341 | void *rx_buf, int words, int fs) | ||
342 | { | ||
343 | u32 *buf_32 = rx_buf; | ||
344 | int k; | ||
345 | |||
346 | for (k = 0; k < words; k++) | ||
347 | buf_32[k] = swab32(sh_msiof_read(p, RFDR) >> fs); | ||
348 | } | ||
349 | |||
350 | static void sh_msiof_spi_read_fifo_s32u(struct sh_msiof_spi_priv *p, | ||
351 | void *rx_buf, int words, int fs) | ||
352 | { | ||
353 | u32 *buf_32 = rx_buf; | ||
354 | int k; | ||
355 | |||
356 | for (k = 0; k < words; k++) | ||
357 | put_unaligned(swab32(sh_msiof_read(p, RFDR) >> fs), &buf_32[k]); | ||
358 | } | ||
359 | |||
322 | static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) | 360 | static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) |
323 | { | 361 | { |
324 | int bits; | 362 | int bits; |
325 | 363 | ||
326 | bits = t ? t->bits_per_word : 0; | 364 | bits = t ? t->bits_per_word : 0; |
327 | bits = bits ? bits : spi->bits_per_word; | 365 | if (!bits) |
366 | bits = spi->bits_per_word; | ||
328 | return bits; | 367 | return bits; |
329 | } | 368 | } |
330 | 369 | ||
@@ -334,7 +373,8 @@ static unsigned long sh_msiof_spi_hz(struct spi_device *spi, | |||
334 | unsigned long hz; | 373 | unsigned long hz; |
335 | 374 | ||
336 | hz = t ? t->speed_hz : 0; | 375 | hz = t ? t->speed_hz : 0; |
337 | hz = hz ? hz : spi->max_speed_hz; | 376 | if (!hz) |
377 | hz = spi->max_speed_hz; | ||
338 | return hz; | 378 | return hz; |
339 | } | 379 | } |
340 | 380 | ||
@@ -468,9 +508,17 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
468 | int bytes_done; | 508 | int bytes_done; |
469 | int words; | 509 | int words; |
470 | int n; | 510 | int n; |
511 | bool swab; | ||
471 | 512 | ||
472 | bits = sh_msiof_spi_bits(spi, t); | 513 | bits = sh_msiof_spi_bits(spi, t); |
473 | 514 | ||
515 | if (bits <= 8 && t->len > 15 && !(t->len & 3)) { | ||
516 | bits = 32; | ||
517 | swab = true; | ||
518 | } else { | ||
519 | swab = false; | ||
520 | } | ||
521 | |||
474 | /* setup bytes per word and fifo read/write functions */ | 522 | /* setup bytes per word and fifo read/write functions */ |
475 | if (bits <= 8) { | 523 | if (bits <= 8) { |
476 | bytes_per_word = 1; | 524 | bytes_per_word = 1; |
@@ -487,6 +535,17 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
487 | rx_fifo = sh_msiof_spi_read_fifo_16u; | 535 | rx_fifo = sh_msiof_spi_read_fifo_16u; |
488 | else | 536 | else |
489 | rx_fifo = sh_msiof_spi_read_fifo_16; | 537 | rx_fifo = sh_msiof_spi_read_fifo_16; |
538 | } else if (swab) { | ||
539 | bytes_per_word = 4; | ||
540 | if ((unsigned long)t->tx_buf & 0x03) | ||
541 | tx_fifo = sh_msiof_spi_write_fifo_s32u; | ||
542 | else | ||
543 | tx_fifo = sh_msiof_spi_write_fifo_s32; | ||
544 | |||
545 | if ((unsigned long)t->rx_buf & 0x03) | ||
546 | rx_fifo = sh_msiof_spi_read_fifo_s32u; | ||
547 | else | ||
548 | rx_fifo = sh_msiof_spi_read_fifo_s32; | ||
490 | } else { | 549 | } else { |
491 | bytes_per_word = 4; | 550 | bytes_per_word = 4; |
492 | if ((unsigned long)t->tx_buf & 0x03) | 551 | if ((unsigned long)t->tx_buf & 0x03) |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 603428213d21..d9fd86211365 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/compat.h> | ||
33 | 34 | ||
34 | #include <linux/spi/spi.h> | 35 | #include <linux/spi/spi.h> |
35 | #include <linux/spi/spidev.h> | 36 | #include <linux/spi/spidev.h> |
@@ -471,6 +472,16 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
471 | return retval; | 472 | return retval; |
472 | } | 473 | } |
473 | 474 | ||
475 | #ifdef CONFIG_COMPAT | ||
476 | static long | ||
477 | spidev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
478 | { | ||
479 | return spidev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); | ||
480 | } | ||
481 | #else | ||
482 | #define spidev_compat_ioctl NULL | ||
483 | #endif /* CONFIG_COMPAT */ | ||
484 | |||
474 | static int spidev_open(struct inode *inode, struct file *filp) | 485 | static int spidev_open(struct inode *inode, struct file *filp) |
475 | { | 486 | { |
476 | struct spidev_data *spidev; | 487 | struct spidev_data *spidev; |
@@ -543,6 +554,7 @@ static const struct file_operations spidev_fops = { | |||
543 | .write = spidev_write, | 554 | .write = spidev_write, |
544 | .read = spidev_read, | 555 | .read = spidev_read, |
545 | .unlocked_ioctl = spidev_ioctl, | 556 | .unlocked_ioctl = spidev_ioctl, |
557 | .compat_ioctl = spidev_compat_ioctl, | ||
546 | .open = spidev_open, | 558 | .open = spidev_open, |
547 | .release = spidev_release, | 559 | .release = spidev_release, |
548 | .llseek = no_llseek, | 560 | .llseek = no_llseek, |