aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-04 08:44:16 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-04 08:44:16 -0400
commit695a461296e5df148c99ac087b9e1cb380f4db15 (patch)
tree951893036fdc0b7bae0e17bc739ac8ffe909781d /drivers/spi
parentc7084b35eb1a4d3353a501508baf9d3d82822c93 (diff)
parent2b681fafcc50fea6304ed418667c9d04282acb73 (diff)
Merge branch 'amd-iommu/2.6.32' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu into core/iommu
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/omap2_mcspi.c32
-rw-r--r--drivers/spi/spi_s3c24xx.c23
2 files changed, 42 insertions, 13 deletions
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index eee4b6e0af2c..9b80ad36dbba 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -59,6 +59,8 @@
59 59
60/* per-register bitmasks: */ 60/* per-register bitmasks: */
61 61
62#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
63#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP (1 << 2)
62#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0) 64#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0)
63#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1) 65#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1)
64 66
@@ -90,6 +92,7 @@
90 92
91#define OMAP2_MCSPI_CHCTRL_EN (1 << 0) 93#define OMAP2_MCSPI_CHCTRL_EN (1 << 0)
92 94
95#define OMAP2_MCSPI_WAKEUPENABLE_WKEN (1 << 0)
93 96
94/* We have 2 DMA channels per CS, one for RX and one for TX */ 97/* We have 2 DMA channels per CS, one for RX and one for TX */
95struct omap2_mcspi_dma { 98struct omap2_mcspi_dma {
@@ -269,7 +272,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
269 272
270 if (rx != NULL) { 273 if (rx != NULL) {
271 omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel, 274 omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel,
272 data_type, element_count, 1, 275 data_type, element_count - 1, 1,
273 OMAP_DMA_SYNC_ELEMENT, 276 OMAP_DMA_SYNC_ELEMENT,
274 mcspi_dma->dma_rx_sync_dev, 1); 277 mcspi_dma->dma_rx_sync_dev, 1);
275 278
@@ -300,6 +303,25 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
300 if (rx != NULL) { 303 if (rx != NULL) {
301 wait_for_completion(&mcspi_dma->dma_rx_completion); 304 wait_for_completion(&mcspi_dma->dma_rx_completion);
302 dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE); 305 dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE);
306 omap2_mcspi_set_enable(spi, 0);
307 if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
308 & OMAP2_MCSPI_CHSTAT_RXS)) {
309 u32 w;
310
311 w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0);
312 if (word_len <= 8)
313 ((u8 *)xfer->rx_buf)[element_count - 1] = w;
314 else if (word_len <= 16)
315 ((u16 *)xfer->rx_buf)[element_count - 1] = w;
316 else /* word_len <= 32 */
317 ((u32 *)xfer->rx_buf)[element_count - 1] = w;
318 } else {
319 dev_err(&spi->dev, "DMA RX last word empty");
320 count -= (word_len <= 8) ? 1 :
321 (word_len <= 16) ? 2 :
322 /* word_len <= 32 */ 4;
323 }
324 omap2_mcspi_set_enable(spi, 1);
303 } 325 }
304 return count; 326 return count;
305} 327}
@@ -873,8 +895,12 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi)
873 } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); 895 } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
874 896
875 mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, 897 mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
876 /* (3 << 8) | (2 << 3) | */ 898 OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
877 OMAP2_MCSPI_SYSCONFIG_AUTOIDLE); 899 OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
900 OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
901
902 mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
903 OMAP2_MCSPI_WAKEUPENABLE_WKEN);
878 904
879 omap2_mcspi_set_master_mode(master); 905 omap2_mcspi_set_master_mode(master);
880 906
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index e0d44af4745a..3f3119d760db 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -111,29 +111,32 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi,
111 unsigned int bpw; 111 unsigned int bpw;
112 unsigned int hz; 112 unsigned int hz;
113 unsigned int div; 113 unsigned int div;
114 unsigned long clk;
114 115
115 bpw = t ? t->bits_per_word : spi->bits_per_word; 116 bpw = t ? t->bits_per_word : spi->bits_per_word;
116 hz = t ? t->speed_hz : spi->max_speed_hz; 117 hz = t ? t->speed_hz : spi->max_speed_hz;
117 118
119 if (!bpw)
120 bpw = 8;
121
122 if (!hz)
123 hz = spi->max_speed_hz;
124
118 if (bpw != 8) { 125 if (bpw != 8) {
119 dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); 126 dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
120 return -EINVAL; 127 return -EINVAL;
121 } 128 }
122 129
123 div = clk_get_rate(hw->clk) / hz; 130 clk = clk_get_rate(hw->clk);
124 131 div = DIV_ROUND_UP(clk, hz * 2) - 1;
125 /* is clk = pclk / (2 * (pre+1)), or is it
126 * clk = (pclk * 2) / ( pre + 1) */
127
128 div /= 2;
129
130 if (div > 0)
131 div -= 1;
132 132
133 if (div > 255) 133 if (div > 255)
134 div = 255; 134 div = 255;
135 135
136 dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz); 136 dev_dbg(&spi->dev, "setting pre-scaler to %d (wanted %d, got %ld)\n",
137 div, hz, clk / (2 * (div + 1)));
138
139
137 writeb(div, hw->regs + S3C2410_SPPRE); 140 writeb(div, hw->regs + S3C2410_SPPRE);
138 141
139 spin_lock(&hw->bitbang.lock); 142 spin_lock(&hw->bitbang.lock);