aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/pxa2xx_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/pxa2xx_spi.c')
-rw-r--r--drivers/spi/pxa2xx_spi.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 34c7c9875681..a7b9070e1b46 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -144,7 +144,6 @@ struct driver_data {
144 size_t tx_map_len; 144 size_t tx_map_len;
145 u8 n_bytes; 145 u8 n_bytes;
146 u32 dma_width; 146 u32 dma_width;
147 int cs_change;
148 int (*write)(struct driver_data *drv_data); 147 int (*write)(struct driver_data *drv_data);
149 int (*read)(struct driver_data *drv_data); 148 int (*read)(struct driver_data *drv_data);
150 irqreturn_t (*transfer_handler)(struct driver_data *drv_data); 149 irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
@@ -406,8 +405,45 @@ static void giveback(struct driver_data *drv_data)
406 struct spi_transfer, 405 struct spi_transfer,
407 transfer_list); 406 transfer_list);
408 407
408 /* Delay if requested before any change in chip select */
409 if (last_transfer->delay_usecs)
410 udelay(last_transfer->delay_usecs);
411
412 /* Drop chip select UNLESS cs_change is true or we are returning
413 * a message with an error, or next message is for another chip
414 */
409 if (!last_transfer->cs_change) 415 if (!last_transfer->cs_change)
410 drv_data->cs_control(PXA2XX_CS_DEASSERT); 416 drv_data->cs_control(PXA2XX_CS_DEASSERT);
417 else {
418 struct spi_message *next_msg;
419
420 /* Holding of cs was hinted, but we need to make sure
421 * the next message is for the same chip. Don't waste
422 * time with the following tests unless this was hinted.
423 *
424 * We cannot postpone this until pump_messages, because
425 * after calling msg->complete (below) the driver that
426 * sent the current message could be unloaded, which
427 * could invalidate the cs_control() callback...
428 */
429
430 /* get a pointer to the next message, if any */
431 spin_lock_irqsave(&drv_data->lock, flags);
432 if (list_empty(&drv_data->queue))
433 next_msg = NULL;
434 else
435 next_msg = list_entry(drv_data->queue.next,
436 struct spi_message, queue);
437 spin_unlock_irqrestore(&drv_data->lock, flags);
438
439 /* see if the next and current messages point
440 * to the same chip
441 */
442 if (next_msg && next_msg->spi != msg->spi)
443 next_msg = NULL;
444 if (!next_msg || msg->state == ERROR_STATE)
445 drv_data->cs_control(PXA2XX_CS_DEASSERT);
446 }
411 447
412 msg->state = NULL; 448 msg->state = NULL;
413 if (msg->complete) 449 if (msg->complete)
@@ -490,10 +526,9 @@ static void dma_transfer_complete(struct driver_data *drv_data)
490 msg->actual_length += drv_data->len - 526 msg->actual_length += drv_data->len -
491 (drv_data->rx_end - drv_data->rx); 527 (drv_data->rx_end - drv_data->rx);
492 528
493 /* Release chip select if requested, transfer delays are 529 /* Transfer delays and chip select release are
494 * handled in pump_transfers */ 530 * handled in pump_transfers or giveback
495 if (drv_data->cs_change) 531 */
496 drv_data->cs_control(PXA2XX_CS_DEASSERT);
497 532
498 /* Move to next transfer */ 533 /* Move to next transfer */
499 msg->state = next_transfer(drv_data); 534 msg->state = next_transfer(drv_data);
@@ -602,10 +637,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
602 drv_data->cur_msg->actual_length += drv_data->len - 637 drv_data->cur_msg->actual_length += drv_data->len -
603 (drv_data->rx_end - drv_data->rx); 638 (drv_data->rx_end - drv_data->rx);
604 639
605 /* Release chip select if requested, transfer delays are 640 /* Transfer delays and chip select release are
606 * handled in pump_transfers */ 641 * handled in pump_transfers or giveback
607 if (drv_data->cs_change) 642 */
608 drv_data->cs_control(PXA2XX_CS_DEASSERT);
609 643
610 /* Move to next transfer */ 644 /* Move to next transfer */
611 drv_data->cur_msg->state = next_transfer(drv_data); 645 drv_data->cur_msg->state = next_transfer(drv_data);
@@ -840,13 +874,17 @@ static void pump_transfers(unsigned long data)
840 return; 874 return;
841 } 875 }
842 876
843 /* Delay if requested at end of transfer*/ 877 /* Delay if requested at end of transfer before CS change */
844 if (message->state == RUNNING_STATE) { 878 if (message->state == RUNNING_STATE) {
845 previous = list_entry(transfer->transfer_list.prev, 879 previous = list_entry(transfer->transfer_list.prev,
846 struct spi_transfer, 880 struct spi_transfer,
847 transfer_list); 881 transfer_list);
848 if (previous->delay_usecs) 882 if (previous->delay_usecs)
849 udelay(previous->delay_usecs); 883 udelay(previous->delay_usecs);
884
885 /* Drop chip select only if cs_change is requested */
886 if (previous->cs_change)
887 drv_data->cs_control(PXA2XX_CS_DEASSERT);
850 } 888 }
851 889
852 /* Check transfer length */ 890 /* Check transfer length */
@@ -878,7 +916,6 @@ static void pump_transfers(unsigned long data)
878 drv_data->len = transfer->len & DCMD_LENGTH; 916 drv_data->len = transfer->len & DCMD_LENGTH;
879 drv_data->write = drv_data->tx ? chip->write : null_writer; 917 drv_data->write = drv_data->tx ? chip->write : null_writer;
880 drv_data->read = drv_data->rx ? chip->read : null_reader; 918 drv_data->read = drv_data->rx ? chip->read : null_reader;
881 drv_data->cs_change = transfer->cs_change;
882 919
883 /* Change speed and bit per word on a per transfer */ 920 /* Change speed and bit per word on a per transfer */
884 cr0 = chip->cr0; 921 cr0 = chip->cr0;