aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi/omap2_mcspi.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-08-09 12:46:45 +0200
committerIngo Molnar <mingo@elte.hu>2009-08-09 12:46:49 +0200
commite3560336be655c6791316482fe288b119f34c427 (patch)
tree43ca9a6b489aaa3918b773f78a7eda37458ef0a8 /drivers/spi/omap2_mcspi.c
parent26528e773ecc74fb1b61b7275f86f761cbb340ec (diff)
parent7b2aa037e878c939676675969983284a02958ae3 (diff)
Merge branch 'linus' into tracing/urgent
Merge reason: Merge up to almost-rc6 to pick up latest perfcounters (on which we'll queue up a dependent fix) Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/spi/omap2_mcspi.c')
-rw-r--r--drivers/spi/omap2_mcspi.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index eee4b6e0af2..9b80ad36dbb 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -59,6 +59,8 @@
/* per-register bitmasks: */
+#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
+#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP (1 << 2)
#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0)
#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1)
@@ -90,6 +92,7 @@
#define OMAP2_MCSPI_CHCTRL_EN (1 << 0)
+#define OMAP2_MCSPI_WAKEUPENABLE_WKEN (1 << 0)
/* We have 2 DMA channels per CS, one for RX and one for TX */
struct omap2_mcspi_dma {
@@ -269,7 +272,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
if (rx != NULL) {
omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel,
- data_type, element_count, 1,
+ data_type, element_count - 1, 1,
OMAP_DMA_SYNC_ELEMENT,
mcspi_dma->dma_rx_sync_dev, 1);
@@ -300,6 +303,25 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
if (rx != NULL) {
wait_for_completion(&mcspi_dma->dma_rx_completion);
dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE);
+ omap2_mcspi_set_enable(spi, 0);
+ if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
+ & OMAP2_MCSPI_CHSTAT_RXS)) {
+ u32 w;
+
+ w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0);
+ if (word_len <= 8)
+ ((u8 *)xfer->rx_buf)[element_count - 1] = w;
+ else if (word_len <= 16)
+ ((u16 *)xfer->rx_buf)[element_count - 1] = w;
+ else /* word_len <= 32 */
+ ((u32 *)xfer->rx_buf)[element_count - 1] = w;
+ } else {
+ dev_err(&spi->dev, "DMA RX last word empty");
+ count -= (word_len <= 8) ? 1 :
+ (word_len <= 16) ? 2 :
+ /* word_len <= 32 */ 4;
+ }
+ omap2_mcspi_set_enable(spi, 1);
}
return count;
}
@@ -873,8 +895,12 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi)
} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
- /* (3 << 8) | (2 << 3) | */
- OMAP2_MCSPI_SYSCONFIG_AUTOIDLE);
+ OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
+ OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
+ OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
+
+ mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
+ OMAP2_MCSPI_WAKEUPENABLE_WKEN);
omap2_mcspi_set_master_mode(master);