diff options
| author | Mark Brown <broonie@linaro.org> | 2013-10-25 04:51:34 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@linaro.org> | 2013-10-25 04:51:34 -0400 |
| commit | 6c99db1eb880cd12c54c810abae7ea7976baf393 (patch) | |
| tree | 29a0099e0b2b19db2e4ba87e70fce8c20faa1abe | |
| parent | 8211e6b8facd9d0da3e8f6e51657cba8b0af19da (diff) | |
| parent | 42e182f86222dee2679c19fb1ab5006354a3be62 (diff) | |
Merge remote-tracking branch 'spi/topic/mxs' into spi-next
| -rw-r--r-- | drivers/spi/spi-mxs.c | 189 |
1 files changed, 80 insertions, 109 deletions
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 312c7f99c4a7..de333059a9a7 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c | |||
| @@ -57,34 +57,53 @@ | |||
| 57 | 57 | ||
| 58 | #define SG_MAXLEN 0xff00 | 58 | #define SG_MAXLEN 0xff00 |
| 59 | 59 | ||
| 60 | /* | ||
| 61 | * Flags for txrx functions. More efficient that using an argument register for | ||
| 62 | * each one. | ||
| 63 | */ | ||
| 64 | #define TXRX_WRITE (1<<0) /* This is a write */ | ||
| 65 | #define TXRX_DEASSERT_CS (1<<1) /* De-assert CS at end of txrx */ | ||
| 66 | |||
| 60 | struct mxs_spi { | 67 | struct mxs_spi { |
| 61 | struct mxs_ssp ssp; | 68 | struct mxs_ssp ssp; |
| 62 | struct completion c; | 69 | struct completion c; |
| 70 | unsigned int sck; /* Rate requested (vs actual) */ | ||
| 63 | }; | 71 | }; |
| 64 | 72 | ||
| 65 | static int mxs_spi_setup_transfer(struct spi_device *dev, | 73 | static int mxs_spi_setup_transfer(struct spi_device *dev, |
| 66 | struct spi_transfer *t) | 74 | const struct spi_transfer *t) |
| 67 | { | 75 | { |
| 68 | struct mxs_spi *spi = spi_master_get_devdata(dev->master); | 76 | struct mxs_spi *spi = spi_master_get_devdata(dev->master); |
| 69 | struct mxs_ssp *ssp = &spi->ssp; | 77 | struct mxs_ssp *ssp = &spi->ssp; |
| 70 | uint32_t hz = 0; | 78 | const unsigned int hz = min(dev->max_speed_hz, t->speed_hz); |
| 71 | 79 | ||
| 72 | hz = dev->max_speed_hz; | ||
| 73 | if (t && t->speed_hz) | ||
| 74 | hz = min(hz, t->speed_hz); | ||
| 75 | if (hz == 0) { | 80 | if (hz == 0) { |
| 76 | dev_err(&dev->dev, "Cannot continue with zero clock\n"); | 81 | dev_err(&dev->dev, "SPI clock rate of zero not allowed\n"); |
| 77 | return -EINVAL; | 82 | return -EINVAL; |
| 78 | } | 83 | } |
| 79 | 84 | ||
| 80 | mxs_ssp_set_clk_rate(ssp, hz); | 85 | if (hz != spi->sck) { |
| 86 | mxs_ssp_set_clk_rate(ssp, hz); | ||
| 87 | /* | ||
| 88 | * Save requested rate, hz, rather than the actual rate, | ||
| 89 | * ssp->clk_rate. Otherwise we would set the rate every trasfer | ||
| 90 | * when the actual rate is not quite the same as requested rate. | ||
| 91 | */ | ||
| 92 | spi->sck = hz; | ||
| 93 | /* | ||
| 94 | * Perhaps we should return an error if the actual clock is | ||
| 95 | * nowhere close to what was requested? | ||
| 96 | */ | ||
| 97 | } | ||
| 98 | |||
| 99 | writel(BM_SSP_CTRL0_LOCK_CS, | ||
| 100 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
| 81 | 101 | ||
| 82 | writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) | | 102 | writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) | |
| 83 | BF_SSP_CTRL1_WORD_LENGTH | 103 | BF_SSP_CTRL1_WORD_LENGTH(BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | |
| 84 | (BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | | 104 | ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | |
| 85 | ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | | 105 | ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), |
| 86 | ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), | 106 | ssp->base + HW_SSP_CTRL1(ssp)); |
| 87 | ssp->base + HW_SSP_CTRL1(ssp)); | ||
| 88 | 107 | ||
| 89 | writel(0x0, ssp->base + HW_SSP_CMD0); | 108 | writel(0x0, ssp->base + HW_SSP_CMD0); |
| 90 | writel(0x0, ssp->base + HW_SSP_CMD1); | 109 | writel(0x0, ssp->base + HW_SSP_CMD1); |
| @@ -94,26 +113,15 @@ static int mxs_spi_setup_transfer(struct spi_device *dev, | |||
| 94 | 113 | ||
| 95 | static int mxs_spi_setup(struct spi_device *dev) | 114 | static int mxs_spi_setup(struct spi_device *dev) |
| 96 | { | 115 | { |
| 97 | int err = 0; | ||
| 98 | |||
| 99 | if (!dev->bits_per_word) | 116 | if (!dev->bits_per_word) |
| 100 | dev->bits_per_word = 8; | 117 | dev->bits_per_word = 8; |
| 101 | 118 | ||
| 102 | if (dev->mode & ~(SPI_CPOL | SPI_CPHA)) | 119 | return 0; |
| 103 | return -EINVAL; | ||
| 104 | |||
| 105 | err = mxs_spi_setup_transfer(dev, NULL); | ||
| 106 | if (err) { | ||
| 107 | dev_err(&dev->dev, | ||
| 108 | "Failed to setup transfer, error = %d\n", err); | ||
| 109 | } | ||
| 110 | |||
| 111 | return err; | ||
| 112 | } | 120 | } |
| 113 | 121 | ||
| 114 | static uint32_t mxs_spi_cs_to_reg(unsigned cs) | 122 | static u32 mxs_spi_cs_to_reg(unsigned cs) |
| 115 | { | 123 | { |
| 116 | uint32_t select = 0; | 124 | u32 select = 0; |
| 117 | 125 | ||
| 118 | /* | 126 | /* |
| 119 | * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0 | 127 | * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0 |
| @@ -131,43 +139,11 @@ static uint32_t mxs_spi_cs_to_reg(unsigned cs) | |||
| 131 | return select; | 139 | return select; |
| 132 | } | 140 | } |
| 133 | 141 | ||
| 134 | static void mxs_spi_set_cs(struct mxs_spi *spi, unsigned cs) | ||
| 135 | { | ||
| 136 | const uint32_t mask = | ||
| 137 | BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ; | ||
| 138 | uint32_t select; | ||
| 139 | struct mxs_ssp *ssp = &spi->ssp; | ||
| 140 | |||
| 141 | writel(mask, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
| 142 | select = mxs_spi_cs_to_reg(cs); | ||
| 143 | writel(select, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
| 144 | } | ||
| 145 | |||
| 146 | static inline void mxs_spi_enable(struct mxs_spi *spi) | ||
| 147 | { | ||
| 148 | struct mxs_ssp *ssp = &spi->ssp; | ||
| 149 | |||
| 150 | writel(BM_SSP_CTRL0_LOCK_CS, | ||
| 151 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
| 152 | writel(BM_SSP_CTRL0_IGNORE_CRC, | ||
| 153 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
| 154 | } | ||
| 155 | |||
| 156 | static inline void mxs_spi_disable(struct mxs_spi *spi) | ||
| 157 | { | ||
| 158 | struct mxs_ssp *ssp = &spi->ssp; | ||
| 159 | |||
| 160 | writel(BM_SSP_CTRL0_LOCK_CS, | ||
| 161 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
| 162 | writel(BM_SSP_CTRL0_IGNORE_CRC, | ||
| 163 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
| 164 | } | ||
| 165 | |||
| 166 | static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set) | 142 | static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set) |
| 167 | { | 143 | { |
| 168 | const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT); | 144 | const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT); |
| 169 | struct mxs_ssp *ssp = &spi->ssp; | 145 | struct mxs_ssp *ssp = &spi->ssp; |
| 170 | uint32_t reg; | 146 | u32 reg; |
| 171 | 147 | ||
| 172 | do { | 148 | do { |
| 173 | reg = readl_relaxed(ssp->base + offset); | 149 | reg = readl_relaxed(ssp->base + offset); |
| @@ -200,9 +176,9 @@ static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id) | |||
| 200 | return IRQ_HANDLED; | 176 | return IRQ_HANDLED; |
| 201 | } | 177 | } |
| 202 | 178 | ||
| 203 | static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | 179 | static int mxs_spi_txrx_dma(struct mxs_spi *spi, |
| 204 | unsigned char *buf, int len, | 180 | unsigned char *buf, int len, |
| 205 | int *first, int *last, int write) | 181 | unsigned int flags) |
| 206 | { | 182 | { |
| 207 | struct mxs_ssp *ssp = &spi->ssp; | 183 | struct mxs_ssp *ssp = &spi->ssp; |
| 208 | struct dma_async_tx_descriptor *desc = NULL; | 184 | struct dma_async_tx_descriptor *desc = NULL; |
| @@ -211,11 +187,11 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | |||
| 211 | const int sgs = DIV_ROUND_UP(len, desc_len); | 187 | const int sgs = DIV_ROUND_UP(len, desc_len); |
| 212 | int sg_count; | 188 | int sg_count; |
| 213 | int min, ret; | 189 | int min, ret; |
| 214 | uint32_t ctrl0; | 190 | u32 ctrl0; |
| 215 | struct page *vm_page; | 191 | struct page *vm_page; |
| 216 | void *sg_buf; | 192 | void *sg_buf; |
| 217 | struct { | 193 | struct { |
| 218 | uint32_t pio[4]; | 194 | u32 pio[4]; |
| 219 | struct scatterlist sg; | 195 | struct scatterlist sg; |
| 220 | } *dma_xfer; | 196 | } *dma_xfer; |
| 221 | 197 | ||
| @@ -228,21 +204,25 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | |||
| 228 | 204 | ||
| 229 | INIT_COMPLETION(spi->c); | 205 | INIT_COMPLETION(spi->c); |
| 230 | 206 | ||
| 207 | /* Chip select was already programmed into CTRL0 */ | ||
| 231 | ctrl0 = readl(ssp->base + HW_SSP_CTRL0); | 208 | ctrl0 = readl(ssp->base + HW_SSP_CTRL0); |
| 232 | ctrl0 &= ~BM_SSP_CTRL0_XFER_COUNT; | 209 | ctrl0 &= ~(BM_SSP_CTRL0_XFER_COUNT | BM_SSP_CTRL0_IGNORE_CRC | |
| 233 | ctrl0 |= BM_SSP_CTRL0_DATA_XFER | mxs_spi_cs_to_reg(cs); | 210 | BM_SSP_CTRL0_READ); |
| 211 | ctrl0 |= BM_SSP_CTRL0_DATA_XFER; | ||
| 234 | 212 | ||
| 235 | if (*first) | 213 | if (!(flags & TXRX_WRITE)) |
| 236 | ctrl0 |= BM_SSP_CTRL0_LOCK_CS; | ||
| 237 | if (!write) | ||
| 238 | ctrl0 |= BM_SSP_CTRL0_READ; | 214 | ctrl0 |= BM_SSP_CTRL0_READ; |
| 239 | 215 | ||
| 240 | /* Queue the DMA data transfer. */ | 216 | /* Queue the DMA data transfer. */ |
| 241 | for (sg_count = 0; sg_count < sgs; sg_count++) { | 217 | for (sg_count = 0; sg_count < sgs; sg_count++) { |
| 218 | /* Prepare the transfer descriptor. */ | ||
| 242 | min = min(len, desc_len); | 219 | min = min(len, desc_len); |
| 243 | 220 | ||
| 244 | /* Prepare the transfer descriptor. */ | 221 | /* |
| 245 | if ((sg_count + 1 == sgs) && *last) | 222 | * De-assert CS on last segment if flag is set (i.e., no more |
| 223 | * transfers will follow) | ||
| 224 | */ | ||
| 225 | if ((sg_count + 1 == sgs) && (flags & TXRX_DEASSERT_CS)) | ||
| 246 | ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC; | 226 | ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC; |
| 247 | 227 | ||
| 248 | if (ssp->devid == IMX23_SSP) { | 228 | if (ssp->devid == IMX23_SSP) { |
| @@ -267,7 +247,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | |||
| 267 | 247 | ||
| 268 | sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min); | 248 | sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min); |
| 269 | ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, | 249 | ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, |
| 270 | write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 250 | (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
| 271 | 251 | ||
| 272 | len -= min; | 252 | len -= min; |
| 273 | buf += min; | 253 | buf += min; |
| @@ -287,7 +267,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | |||
| 287 | 267 | ||
| 288 | desc = dmaengine_prep_slave_sg(ssp->dmach, | 268 | desc = dmaengine_prep_slave_sg(ssp->dmach, |
| 289 | &dma_xfer[sg_count].sg, 1, | 269 | &dma_xfer[sg_count].sg, 1, |
| 290 | write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, | 270 | (flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, |
| 291 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 271 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 292 | 272 | ||
| 293 | if (!desc) { | 273 | if (!desc) { |
| @@ -324,7 +304,7 @@ err_vmalloc: | |||
| 324 | while (--sg_count >= 0) { | 304 | while (--sg_count >= 0) { |
| 325 | err_mapped: | 305 | err_mapped: |
| 326 | dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, | 306 | dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, |
| 327 | write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 307 | (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
| 328 | } | 308 | } |
| 329 | 309 | ||
| 330 | kfree(dma_xfer); | 310 | kfree(dma_xfer); |
| @@ -332,20 +312,19 @@ err_mapped: | |||
| 332 | return ret; | 312 | return ret; |
| 333 | } | 313 | } |
| 334 | 314 | ||
| 335 | static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs, | 315 | static int mxs_spi_txrx_pio(struct mxs_spi *spi, |
| 336 | unsigned char *buf, int len, | 316 | unsigned char *buf, int len, |
| 337 | int *first, int *last, int write) | 317 | unsigned int flags) |
| 338 | { | 318 | { |
| 339 | struct mxs_ssp *ssp = &spi->ssp; | 319 | struct mxs_ssp *ssp = &spi->ssp; |
| 340 | 320 | ||
| 341 | if (*first) | 321 | writel(BM_SSP_CTRL0_IGNORE_CRC, |
| 342 | mxs_spi_enable(spi); | 322 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); |
| 343 | |||
| 344 | mxs_spi_set_cs(spi, cs); | ||
| 345 | 323 | ||
| 346 | while (len--) { | 324 | while (len--) { |
| 347 | if (*last && len == 0) | 325 | if (len == 0 && (flags & TXRX_DEASSERT_CS)) |
| 348 | mxs_spi_disable(spi); | 326 | writel(BM_SSP_CTRL0_IGNORE_CRC, |
| 327 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
| 349 | 328 | ||
| 350 | if (ssp->devid == IMX23_SSP) { | 329 | if (ssp->devid == IMX23_SSP) { |
| 351 | writel(BM_SSP_CTRL0_XFER_COUNT, | 330 | writel(BM_SSP_CTRL0_XFER_COUNT, |
| @@ -356,7 +335,7 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs, | |||
| 356 | writel(1, ssp->base + HW_SSP_XFER_SIZE); | 335 | writel(1, ssp->base + HW_SSP_XFER_SIZE); |
| 357 | } | 336 | } |
| 358 | 337 | ||
| 359 | if (write) | 338 | if (flags & TXRX_WRITE) |
| 360 | writel(BM_SSP_CTRL0_READ, | 339 | writel(BM_SSP_CTRL0_READ, |
| 361 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | 340 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); |
| 362 | else | 341 | else |
| @@ -369,13 +348,13 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs, | |||
| 369 | if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1)) | 348 | if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1)) |
| 370 | return -ETIMEDOUT; | 349 | return -ETIMEDOUT; |
| 371 | 350 | ||
| 372 | if (write) | 351 | if (flags & TXRX_WRITE) |
| 373 | writel(*buf, ssp->base + HW_SSP_DATA(ssp)); | 352 | writel(*buf, ssp->base + HW_SSP_DATA(ssp)); |
| 374 | 353 | ||
| 375 | writel(BM_SSP_CTRL0_DATA_XFER, | 354 | writel(BM_SSP_CTRL0_DATA_XFER, |
| 376 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | 355 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); |
| 377 | 356 | ||
| 378 | if (!write) { | 357 | if (!(flags & TXRX_WRITE)) { |
| 379 | if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp), | 358 | if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp), |
| 380 | BM_SSP_STATUS_FIFO_EMPTY, 0)) | 359 | BM_SSP_STATUS_FIFO_EMPTY, 0)) |
| 381 | return -ETIMEDOUT; | 360 | return -ETIMEDOUT; |
| @@ -400,14 +379,15 @@ static int mxs_spi_transfer_one(struct spi_master *master, | |||
| 400 | { | 379 | { |
| 401 | struct mxs_spi *spi = spi_master_get_devdata(master); | 380 | struct mxs_spi *spi = spi_master_get_devdata(master); |
| 402 | struct mxs_ssp *ssp = &spi->ssp; | 381 | struct mxs_ssp *ssp = &spi->ssp; |
| 403 | int first, last; | ||
| 404 | struct spi_transfer *t, *tmp_t; | 382 | struct spi_transfer *t, *tmp_t; |
| 383 | unsigned int flag; | ||
| 405 | int status = 0; | 384 | int status = 0; |
| 406 | int cs; | ||
| 407 | |||
| 408 | first = last = 0; | ||
| 409 | 385 | ||
| 410 | cs = m->spi->chip_select; | 386 | /* Program CS register bits here, it will be used for all transfers. */ |
| 387 | writel(BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ, | ||
| 388 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
| 389 | writel(mxs_spi_cs_to_reg(m->spi->chip_select), | ||
| 390 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
| 411 | 391 | ||
| 412 | list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) { | 392 | list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) { |
| 413 | 393 | ||
| @@ -415,16 +395,9 @@ static int mxs_spi_transfer_one(struct spi_master *master, | |||
| 415 | if (status) | 395 | if (status) |
| 416 | break; | 396 | break; |
| 417 | 397 | ||
| 418 | if (&t->transfer_list == m->transfers.next) | 398 | /* De-assert on last transfer, inverted by cs_change flag */ |
| 419 | first = 1; | 399 | flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ? |
| 420 | if (&t->transfer_list == m->transfers.prev) | 400 | TXRX_DEASSERT_CS : 0; |
| 421 | last = 1; | ||
| 422 | if ((t->rx_buf && t->tx_buf) || (t->rx_dma && t->tx_dma)) { | ||
| 423 | dev_err(ssp->dev, | ||
| 424 | "Cannot send and receive simultaneously\n"); | ||
| 425 | status = -EINVAL; | ||
| 426 | break; | ||
| 427 | } | ||
| 428 | 401 | ||
| 429 | /* | 402 | /* |
| 430 | * Small blocks can be transfered via PIO. | 403 | * Small blocks can be transfered via PIO. |
| @@ -441,26 +414,26 @@ static int mxs_spi_transfer_one(struct spi_master *master, | |||
| 441 | STMP_OFFSET_REG_CLR); | 414 | STMP_OFFSET_REG_CLR); |
| 442 | 415 | ||
| 443 | if (t->tx_buf) | 416 | if (t->tx_buf) |
| 444 | status = mxs_spi_txrx_pio(spi, cs, | 417 | status = mxs_spi_txrx_pio(spi, |
| 445 | (void *)t->tx_buf, | 418 | (void *)t->tx_buf, |
| 446 | t->len, &first, &last, 1); | 419 | t->len, flag | TXRX_WRITE); |
| 447 | if (t->rx_buf) | 420 | if (t->rx_buf) |
| 448 | status = mxs_spi_txrx_pio(spi, cs, | 421 | status = mxs_spi_txrx_pio(spi, |
| 449 | t->rx_buf, t->len, | 422 | t->rx_buf, t->len, |
| 450 | &first, &last, 0); | 423 | flag); |
| 451 | } else { | 424 | } else { |
| 452 | writel(BM_SSP_CTRL1_DMA_ENABLE, | 425 | writel(BM_SSP_CTRL1_DMA_ENABLE, |
| 453 | ssp->base + HW_SSP_CTRL1(ssp) + | 426 | ssp->base + HW_SSP_CTRL1(ssp) + |
| 454 | STMP_OFFSET_REG_SET); | 427 | STMP_OFFSET_REG_SET); |
| 455 | 428 | ||
| 456 | if (t->tx_buf) | 429 | if (t->tx_buf) |
| 457 | status = mxs_spi_txrx_dma(spi, cs, | 430 | status = mxs_spi_txrx_dma(spi, |
| 458 | (void *)t->tx_buf, t->len, | 431 | (void *)t->tx_buf, t->len, |
| 459 | &first, &last, 1); | 432 | flag | TXRX_WRITE); |
| 460 | if (t->rx_buf) | 433 | if (t->rx_buf) |
| 461 | status = mxs_spi_txrx_dma(spi, cs, | 434 | status = mxs_spi_txrx_dma(spi, |
| 462 | t->rx_buf, t->len, | 435 | t->rx_buf, t->len, |
| 463 | &first, &last, 0); | 436 | flag); |
| 464 | } | 437 | } |
| 465 | 438 | ||
| 466 | if (status) { | 439 | if (status) { |
| @@ -469,7 +442,6 @@ static int mxs_spi_transfer_one(struct spi_master *master, | |||
| 469 | } | 442 | } |
| 470 | 443 | ||
| 471 | m->actual_length += t->len; | 444 | m->actual_length += t->len; |
| 472 | first = last = 0; | ||
| 473 | } | 445 | } |
| 474 | 446 | ||
| 475 | m->status = status; | 447 | m->status = status; |
| @@ -563,7 +535,6 @@ static int mxs_spi_probe(struct platform_device *pdev) | |||
| 563 | goto out_dma_release; | 535 | goto out_dma_release; |
| 564 | 536 | ||
| 565 | clk_set_rate(ssp->clk, clk_freq); | 537 | clk_set_rate(ssp->clk, clk_freq); |
| 566 | ssp->clk_rate = clk_get_rate(ssp->clk) / 1000; | ||
| 567 | 538 | ||
| 568 | ret = stmp_reset_block(ssp->base); | 539 | ret = stmp_reset_block(ssp->base); |
| 569 | if (ret) | 540 | if (ret) |
