diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-11 13:21:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-11 13:21:16 -0400 |
commit | e0d09e32c9d34edafd790020222050d7701f986f (patch) | |
tree | 665c277d2523d6211ced28ae191f51976035b6d6 | |
parent | d32917eedc3b8a21f40206c8dd655beae5be8795 (diff) | |
parent | 9b1f189e6dfb0483b715e19364c782d2ddee96a0 (diff) |
Merge tag 'spi-fix-v4.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown:
"A bunch of small driver specific fixes that have come up, none of them
remarkable in themselves. One fixes a regression introduced in the
merge window and another two are targetted at stable"
* tag 'spi-fix-v4.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: pxa2xx: Do not detect number of enabled chip selects on Intel SPT
spi: spi-ti-qspi: Handle truncated frames properly
spi: spi-ti-qspi: Fix FLEN and WLEN settings if bits_per_word is overridden
spi: omap2-mcspi: Undo broken fix for dma transfer of vmalloced buffer
spi: spi-fsl-dspi: Fix cs_change handling in message transfer
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 62 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-ti-qspi.c | 45 |
4 files changed, 76 insertions, 37 deletions
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 39412c9097c6..c1a2d747b246 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
@@ -385,8 +385,8 @@ static int dspi_transfer_one_message(struct spi_master *master, | |||
385 | dspi->cur_chip = spi_get_ctldata(spi); | 385 | dspi->cur_chip = spi_get_ctldata(spi); |
386 | dspi->cs = spi->chip_select; | 386 | dspi->cs = spi->chip_select; |
387 | dspi->cs_change = 0; | 387 | dspi->cs_change = 0; |
388 | if (dspi->cur_transfer->transfer_list.next | 388 | if (list_is_last(&dspi->cur_transfer->transfer_list, |
389 | == &dspi->cur_msg->transfers) | 389 | &dspi->cur_msg->transfers) || transfer->cs_change) |
390 | dspi->cs_change = 1; | 390 | dspi->cs_change = 1; |
391 | dspi->void_write_data = dspi->cur_chip->void_write_data; | 391 | dspi->void_write_data = dspi->cur_chip->void_write_data; |
392 | 392 | ||
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 43a02e377b3b..0caa3c8bef46 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -423,12 +423,16 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, | |||
423 | 423 | ||
424 | if (mcspi_dma->dma_tx) { | 424 | if (mcspi_dma->dma_tx) { |
425 | struct dma_async_tx_descriptor *tx; | 425 | struct dma_async_tx_descriptor *tx; |
426 | struct scatterlist sg; | ||
426 | 427 | ||
427 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); | 428 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); |
428 | 429 | ||
429 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl, | 430 | sg_init_table(&sg, 1); |
430 | xfer->tx_sg.nents, DMA_MEM_TO_DEV, | 431 | sg_dma_address(&sg) = xfer->tx_dma; |
431 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 432 | sg_dma_len(&sg) = xfer->len; |
433 | |||
434 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1, | ||
435 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
432 | if (tx) { | 436 | if (tx) { |
433 | tx->callback = omap2_mcspi_tx_callback; | 437 | tx->callback = omap2_mcspi_tx_callback; |
434 | tx->callback_param = spi; | 438 | tx->callback_param = spi; |
@@ -474,15 +478,20 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
474 | 478 | ||
475 | if (mcspi_dma->dma_rx) { | 479 | if (mcspi_dma->dma_rx) { |
476 | struct dma_async_tx_descriptor *tx; | 480 | struct dma_async_tx_descriptor *tx; |
481 | struct scatterlist sg; | ||
477 | 482 | ||
478 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); | 483 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); |
479 | 484 | ||
480 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) | 485 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) |
481 | dma_count -= es; | 486 | dma_count -= es; |
482 | 487 | ||
483 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, xfer->rx_sg.sgl, | 488 | sg_init_table(&sg, 1); |
484 | xfer->rx_sg.nents, DMA_DEV_TO_MEM, | 489 | sg_dma_address(&sg) = xfer->rx_dma; |
485 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 490 | sg_dma_len(&sg) = dma_count; |
491 | |||
492 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, | ||
493 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | | ||
494 | DMA_CTRL_ACK); | ||
486 | if (tx) { | 495 | if (tx) { |
487 | tx->callback = omap2_mcspi_rx_callback; | 496 | tx->callback = omap2_mcspi_rx_callback; |
488 | tx->callback_param = spi; | 497 | tx->callback_param = spi; |
@@ -496,6 +505,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
496 | omap2_mcspi_set_dma_req(spi, 1, 1); | 505 | omap2_mcspi_set_dma_req(spi, 1, 1); |
497 | 506 | ||
498 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 507 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
508 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, | ||
509 | DMA_FROM_DEVICE); | ||
499 | 510 | ||
500 | if (mcspi->fifo_depth > 0) | 511 | if (mcspi->fifo_depth > 0) |
501 | return count; | 512 | return count; |
@@ -608,6 +619,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
608 | 619 | ||
609 | if (tx != NULL) { | 620 | if (tx != NULL) { |
610 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 621 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
622 | dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, | ||
623 | DMA_TO_DEVICE); | ||
611 | 624 | ||
612 | if (mcspi->fifo_depth > 0) { | 625 | if (mcspi->fifo_depth > 0) { |
613 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; | 626 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; |
@@ -1074,16 +1087,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
1074 | gpio_free(spi->cs_gpio); | 1087 | gpio_free(spi->cs_gpio); |
1075 | } | 1088 | } |
1076 | 1089 | ||
1077 | static bool omap2_mcspi_can_dma(struct spi_master *master, | ||
1078 | struct spi_device *spi, | ||
1079 | struct spi_transfer *xfer) | ||
1080 | { | ||
1081 | if (xfer->len < DMA_MIN_BYTES) | ||
1082 | return false; | ||
1083 | |||
1084 | return true; | ||
1085 | } | ||
1086 | |||
1087 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, | 1090 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, |
1088 | struct spi_device *spi, struct spi_transfer *t) | 1091 | struct spi_device *spi, struct spi_transfer *t) |
1089 | { | 1092 | { |
@@ -1265,6 +1268,32 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, | |||
1265 | return -EINVAL; | 1268 | return -EINVAL; |
1266 | } | 1269 | } |
1267 | 1270 | ||
1271 | if (len < DMA_MIN_BYTES) | ||
1272 | goto skip_dma_map; | ||
1273 | |||
1274 | if (mcspi_dma->dma_tx && tx_buf != NULL) { | ||
1275 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, | ||
1276 | len, DMA_TO_DEVICE); | ||
1277 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | ||
1278 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1279 | 'T', len); | ||
1280 | return -EINVAL; | ||
1281 | } | ||
1282 | } | ||
1283 | if (mcspi_dma->dma_rx && rx_buf != NULL) { | ||
1284 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, | ||
1285 | DMA_FROM_DEVICE); | ||
1286 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { | ||
1287 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1288 | 'R', len); | ||
1289 | if (tx_buf != NULL) | ||
1290 | dma_unmap_single(mcspi->dev, t->tx_dma, | ||
1291 | len, DMA_TO_DEVICE); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | skip_dma_map: | ||
1268 | return omap2_mcspi_work_one(mcspi, spi, t); | 1297 | return omap2_mcspi_work_one(mcspi, spi, t); |
1269 | } | 1298 | } |
1270 | 1299 | ||
@@ -1348,7 +1377,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) | |||
1348 | master->transfer_one = omap2_mcspi_transfer_one; | 1377 | master->transfer_one = omap2_mcspi_transfer_one; |
1349 | master->set_cs = omap2_mcspi_set_cs; | 1378 | master->set_cs = omap2_mcspi_set_cs; |
1350 | master->cleanup = omap2_mcspi_cleanup; | 1379 | master->cleanup = omap2_mcspi_cleanup; |
1351 | master->can_dma = omap2_mcspi_can_dma; | ||
1352 | master->dev.of_node = node; | 1380 | master->dev.of_node = node; |
1353 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; | 1381 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; |
1354 | master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; | 1382 | master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 85e59a406a4c..86138e4101b0 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
@@ -126,7 +126,7 @@ static const struct lpss_config lpss_platforms[] = { | |||
126 | .reg_general = -1, | 126 | .reg_general = -1, |
127 | .reg_ssp = 0x20, | 127 | .reg_ssp = 0x20, |
128 | .reg_cs_ctrl = 0x24, | 128 | .reg_cs_ctrl = 0x24, |
129 | .reg_capabilities = 0xfc, | 129 | .reg_capabilities = -1, |
130 | .rx_threshold = 1, | 130 | .rx_threshold = 1, |
131 | .tx_threshold_lo = 32, | 131 | .tx_threshold_lo = 32, |
132 | .tx_threshold_hi = 56, | 132 | .tx_threshold_hi = 56, |
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index eac3c960b2de..443f664534e1 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
@@ -94,6 +94,7 @@ struct ti_qspi { | |||
94 | #define QSPI_FLEN(n) ((n - 1) << 0) | 94 | #define QSPI_FLEN(n) ((n - 1) << 0) |
95 | #define QSPI_WLEN_MAX_BITS 128 | 95 | #define QSPI_WLEN_MAX_BITS 128 |
96 | #define QSPI_WLEN_MAX_BYTES 16 | 96 | #define QSPI_WLEN_MAX_BYTES 16 |
97 | #define QSPI_WLEN_MASK QSPI_WLEN(QSPI_WLEN_MAX_BITS) | ||
97 | 98 | ||
98 | /* STATUS REGISTER */ | 99 | /* STATUS REGISTER */ |
99 | #define BUSY 0x01 | 100 | #define BUSY 0x01 |
@@ -235,16 +236,16 @@ static inline int ti_qspi_poll_wc(struct ti_qspi *qspi) | |||
235 | return -ETIMEDOUT; | 236 | return -ETIMEDOUT; |
236 | } | 237 | } |
237 | 238 | ||
238 | static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) | 239 | static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t, |
240 | int count) | ||
239 | { | 241 | { |
240 | int wlen, count, xfer_len; | 242 | int wlen, xfer_len; |
241 | unsigned int cmd; | 243 | unsigned int cmd; |
242 | const u8 *txbuf; | 244 | const u8 *txbuf; |
243 | u32 data; | 245 | u32 data; |
244 | 246 | ||
245 | txbuf = t->tx_buf; | 247 | txbuf = t->tx_buf; |
246 | cmd = qspi->cmd | QSPI_WR_SNGL; | 248 | cmd = qspi->cmd | QSPI_WR_SNGL; |
247 | count = t->len; | ||
248 | wlen = t->bits_per_word >> 3; /* in bytes */ | 249 | wlen = t->bits_per_word >> 3; /* in bytes */ |
249 | xfer_len = wlen; | 250 | xfer_len = wlen; |
250 | 251 | ||
@@ -304,9 +305,10 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) | |||
304 | return 0; | 305 | return 0; |
305 | } | 306 | } |
306 | 307 | ||
307 | static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) | 308 | static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t, |
309 | int count) | ||
308 | { | 310 | { |
309 | int wlen, count; | 311 | int wlen; |
310 | unsigned int cmd; | 312 | unsigned int cmd; |
311 | u8 *rxbuf; | 313 | u8 *rxbuf; |
312 | 314 | ||
@@ -323,7 +325,6 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) | |||
323 | cmd |= QSPI_RD_SNGL; | 325 | cmd |= QSPI_RD_SNGL; |
324 | break; | 326 | break; |
325 | } | 327 | } |
326 | count = t->len; | ||
327 | wlen = t->bits_per_word >> 3; /* in bytes */ | 328 | wlen = t->bits_per_word >> 3; /* in bytes */ |
328 | 329 | ||
329 | while (count) { | 330 | while (count) { |
@@ -354,12 +355,13 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) | |||
354 | return 0; | 355 | return 0; |
355 | } | 356 | } |
356 | 357 | ||
357 | static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) | 358 | static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t, |
359 | int count) | ||
358 | { | 360 | { |
359 | int ret; | 361 | int ret; |
360 | 362 | ||
361 | if (t->tx_buf) { | 363 | if (t->tx_buf) { |
362 | ret = qspi_write_msg(qspi, t); | 364 | ret = qspi_write_msg(qspi, t, count); |
363 | if (ret) { | 365 | if (ret) { |
364 | dev_dbg(qspi->dev, "Error while writing\n"); | 366 | dev_dbg(qspi->dev, "Error while writing\n"); |
365 | return ret; | 367 | return ret; |
@@ -367,7 +369,7 @@ static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) | |||
367 | } | 369 | } |
368 | 370 | ||
369 | if (t->rx_buf) { | 371 | if (t->rx_buf) { |
370 | ret = qspi_read_msg(qspi, t); | 372 | ret = qspi_read_msg(qspi, t, count); |
371 | if (ret) { | 373 | if (ret) { |
372 | dev_dbg(qspi->dev, "Error while reading\n"); | 374 | dev_dbg(qspi->dev, "Error while reading\n"); |
373 | return ret; | 375 | return ret; |
@@ -450,7 +452,8 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, | |||
450 | struct spi_device *spi = m->spi; | 452 | struct spi_device *spi = m->spi; |
451 | struct spi_transfer *t; | 453 | struct spi_transfer *t; |
452 | int status = 0, ret; | 454 | int status = 0, ret; |
453 | int frame_length; | 455 | unsigned int frame_len_words, transfer_len_words; |
456 | int wlen; | ||
454 | 457 | ||
455 | /* setup device control reg */ | 458 | /* setup device control reg */ |
456 | qspi->dc = 0; | 459 | qspi->dc = 0; |
@@ -462,14 +465,15 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, | |||
462 | if (spi->mode & SPI_CS_HIGH) | 465 | if (spi->mode & SPI_CS_HIGH) |
463 | qspi->dc |= QSPI_CSPOL(spi->chip_select); | 466 | qspi->dc |= QSPI_CSPOL(spi->chip_select); |
464 | 467 | ||
465 | frame_length = (m->frame_length << 3) / spi->bits_per_word; | 468 | frame_len_words = 0; |
466 | 469 | list_for_each_entry(t, &m->transfers, transfer_list) | |
467 | frame_length = clamp(frame_length, 0, QSPI_FRAME); | 470 | frame_len_words += t->len / (t->bits_per_word >> 3); |
471 | frame_len_words = min_t(unsigned int, frame_len_words, QSPI_FRAME); | ||
468 | 472 | ||
469 | /* setup command reg */ | 473 | /* setup command reg */ |
470 | qspi->cmd = 0; | 474 | qspi->cmd = 0; |
471 | qspi->cmd |= QSPI_EN_CS(spi->chip_select); | 475 | qspi->cmd |= QSPI_EN_CS(spi->chip_select); |
472 | qspi->cmd |= QSPI_FLEN(frame_length); | 476 | qspi->cmd |= QSPI_FLEN(frame_len_words); |
473 | 477 | ||
474 | ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); | 478 | ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); |
475 | 479 | ||
@@ -479,16 +483,23 @@ static int ti_qspi_start_transfer_one(struct spi_master *master, | |||
479 | ti_qspi_disable_memory_map(spi); | 483 | ti_qspi_disable_memory_map(spi); |
480 | 484 | ||
481 | list_for_each_entry(t, &m->transfers, transfer_list) { | 485 | list_for_each_entry(t, &m->transfers, transfer_list) { |
482 | qspi->cmd |= QSPI_WLEN(t->bits_per_word); | 486 | qspi->cmd = ((qspi->cmd & ~QSPI_WLEN_MASK) | |
487 | QSPI_WLEN(t->bits_per_word)); | ||
488 | |||
489 | wlen = t->bits_per_word >> 3; | ||
490 | transfer_len_words = min(t->len / wlen, frame_len_words); | ||
483 | 491 | ||
484 | ret = qspi_transfer_msg(qspi, t); | 492 | ret = qspi_transfer_msg(qspi, t, transfer_len_words * wlen); |
485 | if (ret) { | 493 | if (ret) { |
486 | dev_dbg(qspi->dev, "transfer message failed\n"); | 494 | dev_dbg(qspi->dev, "transfer message failed\n"); |
487 | mutex_unlock(&qspi->list_lock); | 495 | mutex_unlock(&qspi->list_lock); |
488 | return -EINVAL; | 496 | return -EINVAL; |
489 | } | 497 | } |
490 | 498 | ||
491 | m->actual_length += t->len; | 499 | m->actual_length += transfer_len_words * wlen; |
500 | frame_len_words -= transfer_len_words; | ||
501 | if (frame_len_words == 0) | ||
502 | break; | ||
492 | } | 503 | } |
493 | 504 | ||
494 | mutex_unlock(&qspi->list_lock); | 505 | mutex_unlock(&qspi->list_lock); |