diff options
-rw-r--r-- | drivers/spi/spi.c | 28 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 4 |
2 files changed, 32 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 77e6e45951f4..c9a8d544e467 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -849,6 +849,20 @@ static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg) | |||
849 | return 0; | 849 | return 0; |
850 | } | 850 | } |
851 | #else /* !CONFIG_HAS_DMA */ | 851 | #else /* !CONFIG_HAS_DMA */ |
852 | static inline int spi_map_buf(struct spi_master *master, | ||
853 | struct device *dev, struct sg_table *sgt, | ||
854 | void *buf, size_t len, | ||
855 | enum dma_data_direction dir) | ||
856 | { | ||
857 | return -EINVAL; | ||
858 | } | ||
859 | |||
860 | static inline void spi_unmap_buf(struct spi_master *master, | ||
861 | struct device *dev, struct sg_table *sgt, | ||
862 | enum dma_data_direction dir) | ||
863 | { | ||
864 | } | ||
865 | |||
852 | static inline int __spi_map_msg(struct spi_master *master, | 866 | static inline int __spi_map_msg(struct spi_master *master, |
853 | struct spi_message *msg) | 867 | struct spi_message *msg) |
854 | { | 868 | { |
@@ -2725,6 +2739,7 @@ int spi_flash_read(struct spi_device *spi, | |||
2725 | 2739 | ||
2726 | { | 2740 | { |
2727 | struct spi_master *master = spi->master; | 2741 | struct spi_master *master = spi->master; |
2742 | struct device *rx_dev = NULL; | ||
2728 | int ret; | 2743 | int ret; |
2729 | 2744 | ||
2730 | if ((msg->opcode_nbits == SPI_NBITS_DUAL || | 2745 | if ((msg->opcode_nbits == SPI_NBITS_DUAL || |
@@ -2750,9 +2765,22 @@ int spi_flash_read(struct spi_device *spi, | |||
2750 | return ret; | 2765 | return ret; |
2751 | } | 2766 | } |
2752 | } | 2767 | } |
2768 | |||
2753 | mutex_lock(&master->bus_lock_mutex); | 2769 | mutex_lock(&master->bus_lock_mutex); |
2770 | if (master->dma_rx) { | ||
2771 | rx_dev = master->dma_rx->device->dev; | ||
2772 | ret = spi_map_buf(master, rx_dev, &msg->rx_sg, | ||
2773 | msg->buf, msg->len, | ||
2774 | DMA_FROM_DEVICE); | ||
2775 | if (!ret) | ||
2776 | msg->cur_msg_mapped = true; | ||
2777 | } | ||
2754 | ret = master->spi_flash_read(spi, msg); | 2778 | ret = master->spi_flash_read(spi, msg); |
2779 | if (msg->cur_msg_mapped) | ||
2780 | spi_unmap_buf(master, rx_dev, &msg->rx_sg, | ||
2781 | DMA_FROM_DEVICE); | ||
2755 | mutex_unlock(&master->bus_lock_mutex); | 2782 | mutex_unlock(&master->bus_lock_mutex); |
2783 | |||
2756 | if (master->auto_runtime_pm) | 2784 | if (master->auto_runtime_pm) |
2757 | pm_runtime_put(master->dev.parent); | 2785 | pm_runtime_put(master->dev.parent); |
2758 | 2786 | ||
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 1f03483f61e5..7b53af4ba5f8 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
@@ -1143,6 +1143,8 @@ static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd) | |||
1143 | * @opcode_nbits: number of lines to send opcode | 1143 | * @opcode_nbits: number of lines to send opcode |
1144 | * @addr_nbits: number of lines to send address | 1144 | * @addr_nbits: number of lines to send address |
1145 | * @data_nbits: number of lines for data | 1145 | * @data_nbits: number of lines for data |
1146 | * @rx_sg: Scatterlist for receive data read from flash | ||
1147 | * @cur_msg_mapped: message has been mapped for DMA | ||
1146 | */ | 1148 | */ |
1147 | struct spi_flash_read_message { | 1149 | struct spi_flash_read_message { |
1148 | void *buf; | 1150 | void *buf; |
@@ -1155,6 +1157,8 @@ struct spi_flash_read_message { | |||
1155 | u8 opcode_nbits; | 1157 | u8 opcode_nbits; |
1156 | u8 addr_nbits; | 1158 | u8 addr_nbits; |
1157 | u8 data_nbits; | 1159 | u8 data_nbits; |
1160 | struct sg_table rx_sg; | ||
1161 | bool cur_msg_mapped; | ||
1158 | }; | 1162 | }; |
1159 | 1163 | ||
1160 | /* SPI core interface for flash read support */ | 1164 | /* SPI core interface for flash read support */ |